Detection rules › Sublime MQL
Sublime MQL rules: attachment
Adobe branded PDF file linking to a password-protected file from untrusted sender
#Detects pdf files with links to a remotely hosted password-protected file. This is a common technique abused by Phishing actors as well as Malware actors (IcedID, Remcos, Async Rat)
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion, Impersonation: Brand, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension == "pdf"
and any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence == "high"
)
and strings.icontains(.scan.ocr.raw, "password-protected")
and any(ml.nlu_classifier(.scan.ocr.raw).entities,
.name == "org" and .text == "Adobe"
)
)
)
Detection logic
Scope: inbound message.
Detects pdf files with links to a remotely hosted password-protected file. This is a common technique abused by Phishing actors as well as Malware actors (IcedID, Remcos, Async Rat)
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where all hold:any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
- .scan.ocr.raw contains 'password-protected'
any of
ml.nlu_classifier(.scan.ocr.raw).entitieswhere all hold:- .name is 'org'
- .text is 'Adobe'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, ml.nlu_classifier, strings.icontains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
strings.icontains | substring | password-protected |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].name | equals | org |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].text | equals | Adobe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].name eq "org"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].text eq "Adobe"
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"
file.explode(attachments[])[].scan.ocr.raw contains "password-protected"
attachments.file_extension eq "pdf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment soliciting user to enable macros
#Recursively scans files and archives to detect documents that ask the user to enable macros, including if that text appears within an embedded image.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
strings.ilike(.scan.ocr.raw, "*please*enable*macros")
or any(.scan.strings.strings,
strings.ilike(., "*please enable macros*")
)
)
)
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.
Recursively scans files and archives to detect documents that ask the user to enable macros, including if that text appears within an embedded image.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where any holds:- .scan.ocr.raw matches '*please*enable*macros'
any of
.scan.strings.stringswhere:- . matches '*please enable macros*'
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, profile.by_sender, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *please*enable*macros |
strings.ilike | substring | *please enable macros* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "please enable macros"
file.explode(attachments[])[].scan.ocr.raw wildcard "*please*enable*macros"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with auto-executing macro (unsolicited)
#Attachment from an unsolicited sender contains a macro that will auto-execute when the file is opened. Macros are a common phishing technique used to deploy malware.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.oletools(.).macros.keywords, .type =~ "autoexec")
)
and (
not profile.by_sender().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
// negate replies
and (length(headers.references) == 0 or headers.in_reply_to is null)
Detection logic
Scope: inbound message.
Attachment from an unsolicited sender contains a macro that will auto-execute when the file is opened. Macros are a common phishing technique used to deploy malware.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.oletools(.).macros.keywordswhere:- .type is 'autoexec'
any of:
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(headers.references) is 0
- headers.in_reply_to is missing
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, headers.in_reply_to, headers.references, type.inbound. Sensors: file.oletools, profile.by_sender. Reference lists: $file_extensions_macros.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.oletools(attachments[]).macros.keywords[].type | equals | autoexec |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
any(file.oletools(attachments).macros.keywords)
file.oletools(attachments).macros.keywords.type eq "autoexec"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
headers.in_reply_to is_null
headers.references length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with auto-opening VBA macro (unsolicited)
#Recursively scans files and archives to detect embedded VBA files with an auto open exec.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.), any(.scan.vba.auto_exec, . == "AutoOpen"))
)
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.
Recursively scans files and archives to detect embedded VBA files with an auto open exec.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where:any of
.scan.vba.auto_execwhere:- . is 'AutoOpen'
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, profile.by_sender. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.explode(attachments[])[].scan.vba.auto_exec[] | equals | AutoOpen |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
any(file.explode(attachments))
any(file.explode(attachments).scan.vba.auto_exec)
file.explode(attachments).scan.vba.auto_exec eq "AutoOpen"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with encrypted zip (unsolicited)
#Recursively scans files and archives to detect encrypted zip files.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Encryption |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_type == "zip" or .file_extension == "zip")
and any(file.explode(.), any(.flavors.yara, . == 'encrypted_zip'))
)
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().prevalence == "common"
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect encrypted zip files.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'zip'
- .file_extension is 'zip'
any of
file.explode(.)where:any of
.flavors.yarawhere:- . is 'encrypted_zip'
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().prevalence is 'common'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, profile.by_sender.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | zip |
attachments[].file_extension | equals | zip |
file.explode(attachments[])[].flavors.yara[] | equals | encrypted_zip |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "encrypted_zip"
or
attachments.file_extension eq "zip"
attachments.file_type eq "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"
not
profile.by_sender func_call "profile.by_sender().solicited"
not
profile.by_sender func_call "profile.by_sender().prevalence == common"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with high risk VBA macro (unsolicited)
#Potentially malicious attachment containing a VBA macro. Oletools categorizes the macro risk as 'high'.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and file.oletools(.).indicators.vba_macros.risk == "high"
)
and (
not profile.by_sender().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
Detection logic
Scope: inbound message.
Potentially malicious attachment containing a VBA macro. Oletools categorizes the macro risk as 'high'.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- file.oletools(.).indicators.vba_macros.risk is 'high'
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.oletools, profile.by_sender. Reference lists: $file_extensions_macros.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
file.oletools func_call "file.oletools(attachments[]).indicators.vba_macros.risk == high"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with macro calling executable
#Recursively scans files and archives to detect embedded VBA files with an encoded hex string referencing an exe. This may be an attempt to heavily obfuscate an execution through Microsoft document.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.), any(.scan.vba.hex, strings.ilike(., "*exe*")))
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect embedded VBA files with an encoded hex string referencing an exe. This may be an attempt to heavily obfuscate an execution through Microsoft document.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where:any of
.scan.vba.hexwhere:- . matches '*exe*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *exe* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
any(file.explode(attachments))
any(file.explode(attachments).scan.vba.hex)
file.explode(attachments).scan.vba.hex match "exe"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with unscannable encrypted zip
#Recursively scans files and archives to detect embedded ZIP files that are encrypted and could not be opened/scanned.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_type == "zip" or .file_extension == "zip")
and any(file.explode(.),
any(.flavors.yara, . == 'encrypted_zip')
and .scan.encrypted_zip.cracked_password == null
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect embedded ZIP files that are encrypted and could not be opened/scanned.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'zip'
- .file_extension is 'zip'
any of
file.explode(.)where all hold:any of
.flavors.yarawhere:- . is 'encrypted_zip'
- .scan.encrypted_zip.cracked_password is None
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | zip |
attachments[].file_extension | equals | zip |
file.explode(attachments[])[].flavors.yara[] | equals | encrypted_zip |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "encrypted_zip"
file.explode(attachments[])[].scan.encrypted_zip.cracked_password eq ""
or
attachments.file_extension eq "zip"
attachments.file_type eq "zip"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment with VBA macros from employee impersonation (unsolicited)
#Attachment contains a VBA macro from a sender your organization has never sent an email to. Sender is using a display name that matches the display name of someone in your organization. VBA macros are a common phishing technique used to deploy malware.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Impersonation: Employee, Macros, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// ensure the display name contains a space to avoid single named process accounts eg. 'billing, payment'
and strings.contains(sender.display_name, " ")
and sender.display_name in~ $org_display_names
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and file.oletools(.).indicators.vba_macros.exists
)
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.
Attachment contains a VBA macro from a sender your organization has never sent an email to. Sender is using a display name that matches the display name of someone in your organization. VBA macros are a common phishing technique used to deploy malware.
- inbound message
- sender.display_name contains ' '
- sender.display_name in $org_display_names
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- file.oletools(.).indicators.vba_macros.exists
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, sender.display_name, type.inbound. Sensors: file.oletools, profile.by_sender, strings.contains. Reference lists: $file_extensions_common_archives, $file_extensions_macros, $org_display_names.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
file.oletools func_call "file.oletools(attachments[]).indicators.vba_macros.exists"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
sender.display_name contains " "
type.inbound eq "true"
macro "sender.display_name in org_display_names"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.display_name | contains | field:"sender.display_name" kind:contains value:" " | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: .csproj with suspicious commands
#Attached .csproj file contains suspicious commands.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension == "csproj"
and any(file.explode(.),
(
(any(.scan.strings.strings, strings.contains(., 'DllImport')))
and (
any(.scan.strings.strings,
strings.icontains(., 'CreateProcess')
)
)
)
)
)
Detection logic
Scope: inbound message.
Attached .csproj file contains suspicious commands.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'csproj'
any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . contains 'DllImport'
any of
.scan.strings.stringswhere:- . contains 'CreateProcess'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.contains, strings.icontains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | csproj |
strings.contains | substring | DllImport |
strings.icontains | substring | CreateProcess |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "CreateProcess"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "DllImport"
attachments.file_extension eq "csproj"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: 7z Archive Containing RAR File
#Detects 7z archive attachments that contain RAR files, which may be used to evade detection by nesting compressed file formats.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
and .file_type == "7z"
)
and any(file.expand_archives(.).files, .file_type == "rar")
)
Detection logic
Scope: inbound message.
Detects 7z archive attachments that contain RAR files, which may be used to evade detection by nesting compressed file formats.
- inbound message
any of
attachmentswhere all hold:all of:
- .file_extension in $file_extensions_common_archives
- .file_type is '7z'
any of
file.expand_archives(.).fileswhere:- .file_type is 'rar'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.expand_archives. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | 7z |
file.expand_archives(attachments[]).files[].file_type | equals | rar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.expand_archives(attachments).files)
file.expand_archives(attachments).files.file_type eq "rar"
attachments.file_type eq "7z"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Adobe image lure in body or attachment with suspicious link
#Detects Adobe phishing messages with an Adobe logo in the body or attachment, with suspicious link language.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Image as content, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
// all images
length(filter(attachments, .file_type not in $file_types_images)) == 0
// only pdf attachments
or length(filter(attachments, .file_type != "pdf")) == 0
// pdf and image attachements where images are all embedded into the message body
or length(filter(attachments,
.file_type == 'pdf'
or (
.file_type in $file_types_images
and strings.icontains(body.html.raw,
strings.concat("cid:", .content_id)
)
)
)
) == length(attachments)
)
and (
(
any(ml.logo_detect(file.message_screenshot()).brands, .name == "Adobe")
and 0 < length(body.links) < 10
and any(body.links, .display_text is null)
and (
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",
"mimecastprotect.com",
"cisco.com"
)
)
) != length(body.links)
)
)
or any(filter(attachments,
// filter down to attachments with adobe logo
any(ml.logo_detect(.).brands,
.name == "Adobe" and .confidence in ("medium", "high")
)
),
// the attachment (or message body) contain links
any(file.explode(.),
(
length(.scan.url.urls) > 0
or length(.scan.pdf.urls) > 0
or length(body.links) > 0
)
)
)
)
and (
(
(length(headers.references) > 0 or headers.in_reply_to is null)
and not (
(
strings.istarts_with(subject.subject, "RE:")
or strings.istarts_with(subject.subject, "RES:")
or strings.istarts_with(subject.subject, "R:")
or strings.istarts_with(subject.subject, "ODG:")
or strings.istarts_with(subject.subject, "答复:")
or strings.istarts_with(subject.subject, "AW:")
or strings.istarts_with(subject.subject, "TR:")
or strings.istarts_with(subject.subject, "FWD:")
or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
)
)
)
or length(headers.references) == 0
)
// not a newsletter or advertisement
and not any(headers.hops, any(.fields, .name == "List-Unsubscribe-Post"))
and not any(ml.nlu_classifier(body.current_thread.text).topics,
.name in ("Advertising and Promotions", "Newsletters and Digests")
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 (
// exclude solicited senders
not profile.by_sender_email().solicited
or profile.by_sender_email().prevalence == "new"
or length(recipients.to) == 0
// domains for recipients to/cc must be valid
or (
all(recipients.to, .email.domain.valid == false)
and all(recipients.cc, .email.domain.valid == false)
)
or (
profile.by_sender_email().any_messages_malicious_or_spam
and not profile.by_sender_email().any_messages_benign
)
)
and not profile.by_sender_email().any_messages_benign
Detection logic
Scope: inbound message.
Detects Adobe phishing messages with an Adobe logo in the body or attachment, with suspicious link language.
- inbound message
any of:
- length(filter(attachments, .file_type not in $file_types_images)) is 0
- length(filter(attachments, .file_type != 'pdf')) is 0
- length(filter(attachments, .file_type == 'pdf' or .file_type in $file_types_images and strings.icontains(body.html.raw, strings.concat('cid:', .content_id)))) is length(attachments)
any of:
all of:
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name is 'Adobe'
all of:
- length(body.links) > 0
- length(body.links) < 10
any of
body.linkswhere:- .display_text is missing
- 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', 'mimecastprotect.com', 'cisco.com'))) is not length(body.links)
any of
filter(attachments)where:any of
file.explode(.)where any holds:- length(.scan.url.urls) > 0
- length(.scan.pdf.urls) > 0
- length(body.links) > 0
any of:
all of:
any of:
- length(headers.references) > 0
- headers.in_reply_to is missing
none of:
- subject.subject starts with 'RE:'
- subject.subject starts with 'RES:'
- subject.subject starts with 'R:'
- subject.subject starts with 'ODG:'
- subject.subject starts with '答复:'
- subject.subject starts with 'AW:'
- subject.subject starts with 'TR:'
- subject.subject starts with 'FWD:'
- subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:'
- length(headers.references) is 0
not:
any of
headers.hopswhere:any of
.fieldswhere:- .name is 'List-Unsubscribe-Post'
not:
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name in ('Advertising and Promotions', 'Newsletters and Digests')
- .confidence is 'high'
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
any of:
not:
- profile.by_sender_email().solicited
- profile.by_sender_email().prevalence is 'new'
- length(recipients.to) is 0
all of:
all of
recipients.towhere:- .email.domain.valid is False
all of
recipients.ccwhere:- .email.domain.valid is False
all of:
- profile.by_sender_email().any_messages_malicious_or_spam
not:
- profile.by_sender_email().any_messages_benign
not:
- profile.by_sender_email().any_messages_benign
Inspects: attachments[].content_id, attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.in_reply_to, headers.references, recipients.cc, recipients.cc[].email.domain.valid, recipients.to, recipients.to[].email.domain.valid, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender_email, regex.imatch, strings.concat, strings.icontains, strings.istarts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.
Indicators matched (9)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
ml.logo_detect(file.message_screenshot()).brands[].name | equals | Adobe |
body.links[].href_url.domain.root_domain | member | aka.ms |
body.links[].href_url.domain.root_domain | member | mimecast.com |
body.links[].href_url.domain.root_domain | member | mimecastprotect.com |
body.links[].href_url.domain.root_domain | member | cisco.com |
ml.logo_detect(attachments[]).brands[].name | equals | Adobe |
ml.logo_detect(attachments[]).brands[].confidence | member | medium |
ml.logo_detect(attachments[]).brands[].confidence | member | high |
Stages and Predicates
Stage 1: mql_rule
and
or
any(filter(attachments))
any(file.explode(filter(attachments)))
or
body.links length_compare "0"
file.explode(filter(attachments)[])[].scan.pdf.urls length_compare "0"
file.explode(filter(attachments)[])[].scan.url.urls length_compare "0"
and
any(body.links)
body.links.display_text is_null
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name eq "Adobe"
body.links length_compare "0"
body.links length_compare "10"
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', 'mimecastprotect.com', 'cisco.com'))) != length(body.links)"
or
and
not
or
subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:"
subject.subject starts_with "AW:"
subject.subject starts_with "FWD:"
subject.subject starts_with "ODG:"
subject.subject starts_with "R:"
subject.subject starts_with "RE:"
subject.subject starts_with "RES:"
subject.subject starts_with "TR:"
subject.subject starts_with "答复:"
or
headers.in_reply_to is_null
headers.references length_compare "0"
headers.references length_compare "0"
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
not
any(headers.hops)
any(headers.hops.fields)
headers.hops.fields.name eq "List-Unsubscribe-Post"
not
any(ml.nlu_classifier(body.current_thread.text).topics)
and
ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
ml.nlu_classifier(body.current_thread.text).topics.name in ["Advertising and Promotions", "Newsletters and Digests"]
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"
and
macro "all(recipients.cc)"
macro "all(recipients.to)"
profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
recipients.to length_compare "0"
or
filter(attachments, .file_type != 'pdf') length_compare "0"
filter(attachments, .file_type not in $file_types_images) length_compare "0"
length func_call "length(filter(attachments, .file_type == 'pdf' or .file_type in $file_types_images and strings.icontains(body.html.raw, strings.concat('cid:', .content_id)))) == length(attachments)"
not
profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
ml.nlu_classifier(body.current_thread.text).topics | array_any | excludes:ml.nlu_classifier(body.current_thread.text).topics |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Any .sap file (unsolicited)
#SAP shortcut files can be abused to run unsanctioned code on endpoints. Use if receiving .sap files is not normal behavior in your environment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments, .file_extension == "sap")
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.
SAP shortcut files can be abused to run unsanctioned code on endpoints. Use if receiving .sap files is not normal behavior in your environment.
- inbound message
any of
attachmentswhere:- .file_extension is 'sap'
any of:
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_extension, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender. Reference lists: $high_trust_sender_root_domains.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | sap |
Stages and Predicates
Stage 1: mql_rule
and
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
or
not
profile.by_sender func_call "profile.by_sender().solicited"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
any(attachments)
attachments.file_extension eq "sap"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Any HTML file (unsolicited)
#Potential HTML smuggling attacks in unsolicited messages. Use if passing HTML files is not normal behavior in your environment. This rule may be expanded to inspect HTML attachments for suspicious code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Tactics and techniques | HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ ('htm', 'html') or .file_type == "html"
)
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 or DMARC is missing
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.
Potential HTML smuggling attacks in unsolicited messages. Use if passing HTML files is not normal behavior in your environment. This rule may be expanded to inspect HTML attachments for suspicious code.
- inbound message
any of
attachmentswhere any holds:- .file_extension in ('htm', 'html')
- .file_type is 'html'
any of:
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender. Reference lists: $high_trust_sender_root_domains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | htm |
attachments[].file_extension | member | html |
attachments[].file_type | equals | html |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
attachments.file_extension in ["htm", "html"]
attachments.file_type eq "html"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
or
not
profile.by_sender func_call "profile.by_sender().solicited"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Any HTML file (untrusted sender)
#Potential HTML smuggling attacks from new senders. Use if passing HTML files is not normal behavior in your environment. This rule may be expanded to inspect HTML attachments for suspicious code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Tactics and techniques | HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ ('htm', 'html') or .file_type == "html"
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign
// negate highly trusted sender domains unless they fail DMARC authentication or DMARC is missing
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.
Potential HTML smuggling attacks from new senders. Use if passing HTML files is not normal behavior in your environment. This rule may be expanded to inspect HTML attachments for suspicious code.
- inbound message
any of
attachmentswhere any holds:- .file_extension in ('htm', 'html')
- .file_type is 'html'
any of:
all of:
- profile.by_sender().prevalence in ('new', 'outlier')
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender. Reference lists: $high_trust_sender_root_domains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | htm |
attachments[].file_extension | member | html |
attachments[].file_type | equals | html |
Stages and Predicates
Stage 1: mql_rule
and
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"
any(attachments)
or
attachments.file_extension in ["htm", "html"]
attachments.file_type eq "html"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Any HTML file within archive (unsolicited)
#Recursively scans archives to detect HTML files from unsolicited senders. HTML files can be used for HTML smuggling and embedded in archives to evade detection.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.),
.depth > 0 and .file_extension in~ ("html", "htm")
)
)
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.
Recursively scans archives to detect HTML files from unsolicited senders. HTML files can be used for HTML smuggling and embedded in archives to evade detection.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where all hold:- .depth > 0
- .file_extension in ('html', 'htm')
any of:
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, profile.by_sender. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].file_extension | member | html |
file.explode(attachments[])[].file_extension | member | htm |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
file.explode(attachments[])[].depth gt "0"
file.explode(attachments[])[].file_extension in ["htm", "html"]
macro "attachments[].file_extension in file_extensions_common_archives"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive containing disallowed file type
#Recursively scans archives to detect disallowed file types. File extensions can be detected within password-protected archives. Attackers often embed malicious files within archives to bypass email gateway controls.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
or .file_type == "rar"
)
and any(file.explode(.),
.file_extension in~ (
// File types blocked by Gmail by default
// https://support.google.com/mail/answer/6590?hl=en#zippy=%2Cmessages-that-have-attachments
"ade",
"adp",
"apk",
"appx",
"appxbundle",
"bat",
"cab",
"chm",
"cmd",
"com",
"cpl",
"dll",
"dmg",
"ex",
"ex_",
"exe",
"hta",
"ins",
"isp",
"iso",
"jar",
"js",
"jse",
"lib",
"lnk",
"mde",
"msc",
"msi",
"msix",
"msixbundle",
"msp",
"mst",
"nsh",
"pif",
"ps1",
"scr",
"sct",
"shb",
"sys",
"vb",
"vbe",
"vbs",
"vxd",
"wsc",
"wsf",
"wsh",
// File types blocked by Microsoft 365 by default
// https://support.microsoft.com/en-us/office/blocked-attachments-in-outlook-434752e1-02d3-4e90-9124-8b81e49a8519
"ade",
"adp",
"app",
"application",
"appref-ms",
"asp",
"aspx",
"asx",
// "bas", excluded at depth > 1 because they can exist natively in word docs within an archive. see below
"bat",
"bgi",
"cab",
// "cer",
"chm",
"cmd",
"cnt",
"com",
"cpl",
// "crt",
// "csh",
// "der",
"diagcab",
"exe",
"fxp",
"gadget",
// "grp",
"hlp",
"hpj",
"hta",
"htc",
// "inf",
"ins",
"iso",
"isp",
"its",
"jar",
"jnlp",
"js",
"jse",
"ksh",
"lnk",
"mad",
"maf",
"mag",
"mam",
"maq",
"mar",
"mas",
"mat",
"mau",
"mav",
"maw",
"mcf",
"mda",
// "mdb",
"mde",
"mdt",
"mdw",
"mdz",
"msc",
"msh",
"msh1",
"msh2",
"mshxml",
"msh1xml",
"msh2xml",
"msi",
"msp",
"mst",
"msu",
"ops",
"osd",
"pcd",
"pif",
"pl",
"plg",
"prf",
"prg",
"printerexport",
"ps1",
"ps1xml",
"ps2",
"ps2xml",
"psc1",
"psc2",
"psd1",
"psdm1",
"pst",
// "py",
// "pyc",
"pyo",
"pyw",
"pyz",
"pyzw",
"reg",
"scf",
"scr",
"sct",
"shb",
"shs",
"theme",
// "tmp",
"url",
"vb",
"vbe",
"vbp",
"vbs",
"vhd",
"vhdx",
"vsmacros",
"vsw",
"webpnp",
"website",
"ws",
"wsc",
"wsf",
"wsh",
"xbap",
"xll",
"xnk"
)
or (
// BASIC files can naturally occur in word docs,
// so only flag if depth is 1 (archive -> bas, not archive -> doc -> bas)
.depth == 1
and .file_extension =~ "bas"
)
)
)
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.
Recursively scans archives to detect disallowed file types. File extensions can be detected within password-protected archives. Attackers often embed malicious files within archives to bypass email gateway controls.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'rar'
any of
file.explode(.)where any holds:- .file_extension in ('ade', 'adp', 'apk', 'appx', 'appxbundle', 'bat', 'cab', 'chm', 'cmd', 'com', 'cpl', 'dll', 'dmg', 'ex', 'ex_', 'exe', 'hta', 'ins', 'isp', 'iso', 'jar', 'js', 'jse', 'lib', 'lnk', 'mde', 'msc', 'msi', 'msix', 'msixbundle', 'msp', 'mst', 'nsh', 'pif', 'ps1', 'scr', 'sct', 'shb', 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh', 'ade', 'adp', 'app', 'application', 'appref-ms', 'asp', 'aspx', 'asx', 'bat', 'bgi', 'cab', 'chm', 'cmd', 'cnt', 'com', 'cpl', 'diagcab', 'exe', 'fxp', 'gadget', 'hlp', 'hpj', 'hta', 'htc', 'ins', 'iso', 'isp', 'its', 'jar', 'jnlp', 'js', 'jse', 'ksh', 'lnk', 'mad', 'maf', 'mag', 'mam', 'maq', 'mar', 'mas', 'mat', 'mau', 'mav', 'maw', 'mcf', 'mda', 'mde', 'mdt', 'mdw', 'mdz', 'msc', 'msh', 'msh1', 'msh2', 'mshxml', 'msh1xml', 'msh2xml', 'msi', 'msp', 'mst', 'msu', 'ops', 'osd', 'pcd', 'pif', 'pl', 'plg', 'prf', 'prg', 'printerexport', 'ps1', 'ps1xml', 'ps2', 'ps2xml', 'psc1', 'psc2', 'psd1', 'psdm1', 'pst', 'pyo', 'pyw', 'pyz', 'pyzw', 'reg', 'scf', 'scr', 'sct', 'shb', 'shs', 'theme', 'url', 'vb', 'vbe', 'vbp', 'vbs', 'vhd', 'vhdx', 'vsmacros', 'vsw', 'webpnp', 'website', 'ws', 'wsc', 'wsf', 'wsh', 'xbap', 'xll', 'xnk')
all of:
- .depth is 1
- .file_extension is 'bas'
any of:
- profile.by_sender().prevalence in ('new', 'outlier')
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, profile.by_sender. Reference lists: $file_extensions_common_archives.
Indicators matched (124)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rar |
file.explode(attachments[])[].file_extension | member | ade |
file.explode(attachments[])[].file_extension | member | adp |
file.explode(attachments[])[].file_extension | member | apk |
file.explode(attachments[])[].file_extension | member | appx |
file.explode(attachments[])[].file_extension | member | appxbundle |
file.explode(attachments[])[].file_extension | member | bat |
file.explode(attachments[])[].file_extension | member | cab |
file.explode(attachments[])[].file_extension | member | chm |
file.explode(attachments[])[].file_extension | member | cmd |
file.explode(attachments[])[].file_extension | member | com |
file.explode(attachments[])[].file_extension | member | cpl |
112 more
file.explode(attachments[])[].file_extension | member | dll |
file.explode(attachments[])[].file_extension | member | dmg |
file.explode(attachments[])[].file_extension | member | ex |
file.explode(attachments[])[].file_extension | member | ex_ |
file.explode(attachments[])[].file_extension | member | exe |
file.explode(attachments[])[].file_extension | member | hta |
file.explode(attachments[])[].file_extension | member | ins |
file.explode(attachments[])[].file_extension | member | isp |
file.explode(attachments[])[].file_extension | member | iso |
file.explode(attachments[])[].file_extension | member | jar |
file.explode(attachments[])[].file_extension | member | js |
file.explode(attachments[])[].file_extension | member | jse |
file.explode(attachments[])[].file_extension | member | lib |
file.explode(attachments[])[].file_extension | member | lnk |
file.explode(attachments[])[].file_extension | member | mde |
file.explode(attachments[])[].file_extension | member | msc |
file.explode(attachments[])[].file_extension | member | msi |
file.explode(attachments[])[].file_extension | member | msix |
file.explode(attachments[])[].file_extension | member | msixbundle |
file.explode(attachments[])[].file_extension | member | msp |
file.explode(attachments[])[].file_extension | member | mst |
file.explode(attachments[])[].file_extension | member | nsh |
file.explode(attachments[])[].file_extension | member | pif |
file.explode(attachments[])[].file_extension | member | ps1 |
file.explode(attachments[])[].file_extension | member | scr |
file.explode(attachments[])[].file_extension | member | sct |
file.explode(attachments[])[].file_extension | member | shb |
file.explode(attachments[])[].file_extension | member | sys |
file.explode(attachments[])[].file_extension | member | vb |
file.explode(attachments[])[].file_extension | member | vbe |
file.explode(attachments[])[].file_extension | member | vbs |
file.explode(attachments[])[].file_extension | member | vxd |
file.explode(attachments[])[].file_extension | member | wsc |
file.explode(attachments[])[].file_extension | member | wsf |
file.explode(attachments[])[].file_extension | member | wsh |
file.explode(attachments[])[].file_extension | member | app |
file.explode(attachments[])[].file_extension | member | application |
file.explode(attachments[])[].file_extension | member | appref-ms |
file.explode(attachments[])[].file_extension | member | asp |
file.explode(attachments[])[].file_extension | member | aspx |
file.explode(attachments[])[].file_extension | member | asx |
file.explode(attachments[])[].file_extension | member | bgi |
file.explode(attachments[])[].file_extension | member | cnt |
file.explode(attachments[])[].file_extension | member | diagcab |
file.explode(attachments[])[].file_extension | member | fxp |
file.explode(attachments[])[].file_extension | member | gadget |
file.explode(attachments[])[].file_extension | member | hlp |
file.explode(attachments[])[].file_extension | member | hpj |
file.explode(attachments[])[].file_extension | member | htc |
file.explode(attachments[])[].file_extension | member | its |
file.explode(attachments[])[].file_extension | member | jnlp |
file.explode(attachments[])[].file_extension | member | ksh |
file.explode(attachments[])[].file_extension | member | mad |
file.explode(attachments[])[].file_extension | member | maf |
file.explode(attachments[])[].file_extension | member | mag |
file.explode(attachments[])[].file_extension | member | mam |
file.explode(attachments[])[].file_extension | member | maq |
file.explode(attachments[])[].file_extension | member | mar |
file.explode(attachments[])[].file_extension | member | mas |
file.explode(attachments[])[].file_extension | member | mat |
file.explode(attachments[])[].file_extension | member | mau |
file.explode(attachments[])[].file_extension | member | mav |
file.explode(attachments[])[].file_extension | member | maw |
file.explode(attachments[])[].file_extension | member | mcf |
file.explode(attachments[])[].file_extension | member | mda |
file.explode(attachments[])[].file_extension | member | mdt |
file.explode(attachments[])[].file_extension | member | mdw |
file.explode(attachments[])[].file_extension | member | mdz |
file.explode(attachments[])[].file_extension | member | msh |
file.explode(attachments[])[].file_extension | member | msh1 |
file.explode(attachments[])[].file_extension | member | msh2 |
file.explode(attachments[])[].file_extension | member | mshxml |
file.explode(attachments[])[].file_extension | member | msh1xml |
file.explode(attachments[])[].file_extension | member | msh2xml |
file.explode(attachments[])[].file_extension | member | msu |
file.explode(attachments[])[].file_extension | member | ops |
file.explode(attachments[])[].file_extension | member | osd |
file.explode(attachments[])[].file_extension | member | pcd |
file.explode(attachments[])[].file_extension | member | pl |
file.explode(attachments[])[].file_extension | member | plg |
file.explode(attachments[])[].file_extension | member | prf |
file.explode(attachments[])[].file_extension | member | prg |
file.explode(attachments[])[].file_extension | member | printerexport |
file.explode(attachments[])[].file_extension | member | ps1xml |
file.explode(attachments[])[].file_extension | member | ps2 |
file.explode(attachments[])[].file_extension | member | ps2xml |
file.explode(attachments[])[].file_extension | member | psc1 |
file.explode(attachments[])[].file_extension | member | psc2 |
file.explode(attachments[])[].file_extension | member | psd1 |
file.explode(attachments[])[].file_extension | member | psdm1 |
file.explode(attachments[])[].file_extension | member | pst |
file.explode(attachments[])[].file_extension | member | pyo |
file.explode(attachments[])[].file_extension | member | pyw |
file.explode(attachments[])[].file_extension | member | pyz |
file.explode(attachments[])[].file_extension | member | pyzw |
file.explode(attachments[])[].file_extension | member | reg |
file.explode(attachments[])[].file_extension | member | scf |
file.explode(attachments[])[].file_extension | member | shs |
file.explode(attachments[])[].file_extension | member | theme |
file.explode(attachments[])[].file_extension | member | url |
file.explode(attachments[])[].file_extension | member | vbp |
file.explode(attachments[])[].file_extension | member | vhd |
file.explode(attachments[])[].file_extension | member | vhdx |
file.explode(attachments[])[].file_extension | member | vsmacros |
file.explode(attachments[])[].file_extension | member | vsw |
file.explode(attachments[])[].file_extension | member | webpnp |
file.explode(attachments[])[].file_extension | member | website |
file.explode(attachments[])[].file_extension | member | ws |
file.explode(attachments[])[].file_extension | member | xbap |
file.explode(attachments[])[].file_extension | member | xll |
file.explode(attachments[])[].file_extension | member | xnk |
file.explode(attachments[])[].file_extension | equals | bas |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
file.explode(attachments[])[].depth eq "1"
file.explode(attachments[])[].file_extension eq "bas"
file.explode(attachments[])[].file_extension in ["ade", "adp", "apk", "app", "application", "appref-ms", "appx", "appxbundle", "asp", "aspx", "asx", "bat", "bgi", "cab", "chm", "cmd", "cnt", "com", "cpl", "diagcab", "dll", "dmg", "ex", "ex_", "exe", "fxp", "gadget", "hlp", "hpj", "hta", "htc", "ins", "iso", "isp", "its", "jar", "jnlp", "js", "jse", "ksh", "lib", "lnk", "mad", "maf", "mag", "mam", "maq", "mar", "mas", "mat", "mau", "mav", "maw", "mcf", "mda", "mde", "mdt", "mdw", "mdz", "msc", "msh", "msh1", "msh1xml", "msh2", "msh2xml", "mshxml", "msi", "msix", "msixbundle", "msp", "mst", "msu", "nsh", "ops", "osd", "pcd", "pif", "pl", "plg", "prf", "prg", "printerexport", "ps1", "ps1xml", "ps2", "ps2xml", "psc1", "psc2", "psd1", "psdm1", "pst", "pyo", "pyw", "pyz", "pyzw", "reg", "scf", "scr", "sct", "shb", "shs", "sys", "theme", "url", "vb", "vbe", "vbp", "vbs", "vhd", "vhdx", "vsmacros", "vsw", "vxd", "webpnp", "website", "ws", "wsc", "wsf", "wsh", "xbap", "xll", "xnk"]
or
attachments.file_type eq "rar"
macro "attachments[].file_extension in file_extensions_common_archives"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
or
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive containing HTML file with file scheme link
#Attached archive contains an HTML file with a file:// link, likely pointing to an SMB server. This technique can be used to steal NTLM hashes of users who open the HTML file. Known technique of TA577.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Exploit, HTML smuggling, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in $file_extensions_common_archives
and any(file.explode(.),
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .flavors.mime == "text/html"
or any(.flavors.yara, . == "html_file")
)
and any(.scan.url.urls, .scheme == "file")
)
)
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.
Attached archive contains an HTML file with a file:// link, likely pointing to an SMB server. This technique can be used to steal NTLM hashes of users who open the HTML file. Known technique of TA577.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .flavors.mime is 'text/html'
any of
.flavors.yarawhere:- . is 'html_file'
any of
.scan.url.urlswhere:- .scheme is 'file'
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: attachments[].file_extension, type.inbound. Sensors: file.explode, profile.by_sender. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].file_extension | member | html |
file.explode(attachments[])[].file_extension | member | htm |
file.explode(attachments[])[].file_extension | member | shtml |
file.explode(attachments[])[].file_extension | member | dhtml |
file.explode(attachments[])[].flavors.mime | equals | text/html |
file.explode(attachments[])[].flavors.yara[] | equals | html_file |
file.explode(attachments[])[].scan.url.urls[].scheme | equals | file |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "html_file"
file.explode(attachments[])[].file_extension in ["dhtml", "htm", "html", "shtml"]
file.explode(attachments[])[].flavors.mime eq "text/html"
any(file.explode(attachments).scan.url.urls)
file.explode(attachments).scan.url.urls.scheme eq "file"
macro "attachments[].file_extension in file_extensions_common_archives"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive contains DLL-loading macro
#An attacker could send a trusted and signed document that references an untrusted DLL file, which will be loaded by the signed document.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Exploit, LNK, Macros, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
or .file_type == "rar"
)
and (
(
any(file.explode(.),
.scan.zip.encrypted == false
// zip contains a dll file
and any(.scan.zip.all_paths, strings.icontains(., "dll"))
)
and any(file.explode(.),
// macro references a dll file
any(.flavors.yara, strings.like(., "vb_file"))
and any(.scan.strings.strings, strings.icontains(., "dll"))
)
)
or any(file.explode(.), // fallback for encrypted zips
.scan.zip.encrypted == true
and any(.scan.zip.all_paths,
any($file_extensions_macros, strings.icontains(.., .))
)
// zip contains a dll file
and any(.scan.zip.all_paths, strings.icontains(., "dll"))
)
or (
any(file.explode(.),
any(.flavors.yara, strings.like(., "vb_file"))
and any(.scan.strings.strings, strings.ilike(., "*Lib*.dll*"))
)
and any(file.explode(.), strings.ilike(.file_extension, "dll"))
)
)
)
Detection logic
Scope: inbound message.
An attacker could send a trusted and signed document that references an untrusted DLL file, which will be loaded by the signed document.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'rar'
any of:
all of:
any of
file.explode(.)where all hold:- .scan.zip.encrypted is False
any of
.scan.zip.all_pathswhere:- . contains 'dll'
any of
file.explode(.)where all hold:any of
.flavors.yarawhere:- . matches 'vb_file'
any of
.scan.strings.stringswhere:- . contains 'dll'
any of
file.explode(.)where all hold:- .scan.zip.encrypted is True
any of
.scan.zip.all_pathswhere:any of
$file_extensions_macroswhere:- strings.icontains(.)
any of
.scan.zip.all_pathswhere:- . contains 'dll'
all of:
any of
file.explode(.)where all hold:any of
.flavors.yarawhere:- . matches 'vb_file'
any of
.scan.strings.stringswhere:- . matches '*Lib*.dll*'
any of
file.explode(.)where:- .file_extension matches 'dll'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.icontains, strings.ilike, strings.like. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rar |
strings.icontains | substring | dll |
strings.like | substring | vb_file |
strings.ilike | substring | *Lib*.dll* |
strings.ilike | substring | dll |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
any(file.explode(attachments))
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "vb_file"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "dll"
any(file.explode(attachments))
and
any(file.explode(attachments).scan.zip.all_paths)
file.explode(attachments).scan.zip.all_paths contains "dll"
file.explode(attachments[])[].scan.zip.encrypted eq "false"
and
any(file.explode(attachments))
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "vb_file"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*Lib*.dll*"
any(file.explode(attachments))
file.explode(attachments).file_extension eq "dll"
any(file.explode(attachments))
and
any(file.explode(attachments).scan.zip.all_paths)
any($file_extensions_macros)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.zip.all_paths[])"
any(file.explode(attachments).scan.zip.all_paths)
file.explode(attachments).scan.zip.all_paths contains "dll"
file.explode(attachments[])[].scan.zip.encrypted eq "true"
or
attachments.file_type eq "rar"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive with embedded CHM file
#Recursively scans files and archives to detect embedded CHM (Microsoft Compiled HTML Help) files. According to CERT-UA, on March 7, 2022, phishing attacks targeted state organizations of Ukraine using Zip files with embedded CHM documents, which themselves contained malicious VBScript inside a .htm file. The activity is associated with UNC1151, according to CERT-UA.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "chm")
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect embedded CHM (Microsoft Compiled HTML Help) files. According to CERT-UA, on March 7, 2022, phishing attacks targeted state organizations of Ukraine using Zip files with embedded CHM documents, which themselves contained malicious VBScript inside a .htm file. The activity is associated with UNC1151, according to CERT-UA.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'chm'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].file_extension | equals | chm |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "chm"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive with embedded EXE file
#Recursively scans files and archives to detect embedded EXE files (with an MZ header). According to The Record, on June 7, 2021, the Ukrainian Secret Service attributed an attack that used this technique to the "special services of the Russian Federation". The spear-phishing operation urged recipients to download a RAR archive included in the email, which, when decompressed, would drop an EXE file with a double extension (filename.pdf.exe) that tried to pass as a PDF file.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
or .file_type == "rar"
)
and any(file.explode(.),
// the YARA scanner alone can be a bit unreliable,
// it's matched on MZ strings in a text file before
any(.flavors.yara, . == "mz_file")
and strings.starts_with(.flavors.mime, "application")
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect embedded EXE files (with an MZ header). According to The Record, on June 7, 2021, the Ukrainian Secret Service attributed an attack that used this technique to the "special services of the Russian Federation". The spear-phishing operation urged recipients to download a RAR archive included in the email, which, when decompressed, would drop an EXE file with a double extension (filename.pdf.exe) that tried to pass as a PDF file.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'rar'
any of
file.explode(.)where all hold:any of
.flavors.yarawhere:- . is 'mz_file'
- .flavors.mime starts with 'application'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.starts_with. Reference lists: $file_extensions_common_archives.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rar |
file.explode(attachments[])[].flavors.yara[] | equals | mz_file |
strings.starts_with | prefix | application |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "mz_file"
file.explode(attachments[])[].flavors.mime starts_with "application"
or
attachments.file_type eq "rar"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Archive with pdf, txt and wsf files
#Detects a known Qakbot delivery method, zip file with pdf, txt and wsf file at a depth of 1
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ $file_extensions_common_archives
and length(distinct(filter(file.explode(.),
.depth == 1
and .flavors.mime in~ (
"application/pdf",
"text/plain"
)
),
.flavors.mime
)
) == 2
and any(file.explode(.), .depth == 1 and .file_extension == "wsf")
)
Detection logic
Scope: inbound message.
Detects a known Qakbot delivery method, zip file with pdf, txt and wsf file at a depth of 1
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
- length(distinct(filter(file.explode(.), .depth == 1 and .flavors.mime in~ ('application/pdf', 'text/plain')), .flavors.mime)) is 2
any of
file.explode(.)where all hold:- .depth is 1
- .file_extension is 'wsf'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].flavors.mime | member | application/pdf |
file.explode(attachments[])[].flavors.mime | member | text/plain |
file.explode(attachments[])[].file_extension | equals | wsf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
file.explode(attachments[])[].depth eq "1"
file.explode(attachments[])[].file_extension eq "wsf"
distinct(filter(file.explode(attachments[]), attachments[].depth == 1 and attachments[].flavors.mime in~ ('application/pdf', 'text/plain')), attachments[].flavors.mime) length_compare "2"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Base64 encoded bash command in filename
#This rule detects a fileless attack technique where a malicious payload is encoded directly into a filename. This technique is used by threats like VShell. The rule is designed to find these malicious filenames both in direct attachments and within archived files (like .zip, .rar, etc.).
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) > 0
and any(attachments,
(
.file_type in $file_extensions_common_archives
or strings.contains(.file_name, "{")
)
and any(file.expand_archives(.).files,
strings.contains(.file_name, "{")
and (
strings.icontains(.file_name, 'echo,')
or strings.icontains(.file_name, 'base64')
or regex.icontains(.file_name, '\bbash\b')
or any(beta.scan_base64(.file_name, ignore_padding=true),
length(.) >= 10
)
)
)
)
Detection logic
Scope: inbound message.
This rule detects a fileless attack technique where a malicious payload is encoded directly into a filename. This technique is used by threats like VShell. The rule is designed to find these malicious filenames both in direct attachments and within archived files (like .zip, .rar, etc.).
- inbound message
- length(attachments) > 0
any of
attachmentswhere all hold:any of:
- .file_type in $file_extensions_common_archives
- .file_name contains '{'
any of
file.expand_archives(.).fileswhere all hold:- .file_name contains '{'
any of:
- .file_name contains 'echo,'
- .file_name contains 'base64'
- .file_name matches '\\bbash\\b'
any of
beta.scan_base64(.file_name)where:- length(.) ≥ 10
Inspects: attachments[].file_name, attachments[].file_type, type.inbound. Sensors: beta.scan_base64, file.expand_archives, regex.icontains, strings.contains, strings.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | { |
strings.icontains | substring | echo, |
strings.icontains | substring | base64 |
regex.icontains | regex | \bbash\b |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.expand_archives(attachments).files)
and
or
any(beta.scan_base64(file.expand_archives(attachments).files.file_name))
beta.scan_base64(file.expand_archives(attachments).files.file_name) length_compare "10"
file.expand_archives(attachments[]).files[].file_name contains "base64"
file.expand_archives(attachments[]).files[].file_name contains "echo,"
file.expand_archives(attachments[]).files[].file_name regex_match "\\bbash\\b"
file.expand_archives(attachments[]).files[].file_name contains "{"
or
attachments.file_name contains "{"
macro "attachments[].file_type in file_extensions_common_archives"
attachments length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Calendar file with invisible Unicode characters
#Detects calendar (.ics) attachments containing suspicious invisible Unicode characters, which may be used to hide malicious content or bypass security filters. The rule triggers on messages with calendar-related keywords in the subject or body.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and not subject.is_reply
and any(attachments, .file_extension in~ ('ics'))
and any(attachments,
any(file.explode(.),
.file_extension in~ ('ics')
and regex.icontains(.scan.strings.raw,
'[\x{E0000}-\x{E007F}\x{E0100}-\x{E01EF}\x{2062}\x{2064}]{8,}'
)
)
)
and (
regex.icontains(subject.subject, '(calendar|meeting|event|appointment)')
or regex.icontains(body.current_thread.text,
'(calendar|meeting|event|appointment)'
)
or any(attachments, .content_type in~ ("text/calendar"))
)
Detection logic
Scope: inbound message.
Detects calendar (.ics) attachments containing suspicious invisible Unicode characters, which may be used to hide malicious content or bypass security filters. The rule triggers on messages with calendar-related keywords in the subject or body.
- inbound message
not:
- subject.is_reply
any of
attachmentswhere:- .file_extension in ('ics')
any of
attachmentswhere:any of
file.explode(.)where all hold:- .file_extension in ('ics')
- .scan.strings.raw matches '[\\x{E0000}-\\x{E007F}\\x{E0100}-\\x{E01EF}\\x{2062}\\x{2064}]{8,}'
any of:
- subject.subject matches '(calendar|meeting|event|appointment)'
- body.current_thread.text matches '(calendar|meeting|event|appointment)'
any of
attachmentswhere:- .content_type in ('text/calendar')
Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, subject.is_reply, subject.subject, type.inbound. Sensors: file.explode, regex.icontains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
file.explode(attachments[])[].file_extension | member | ics |
regex.icontains | regex | [\x{E0000}-\x{E007F}\x{E0100}-\x{E01EF}\x{2062}\x{2064}]{8,} |
regex.icontains | regex | (calendar|meeting|event|appointment) |
attachments[].content_type | member | text/calendar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.explode(attachments))
and
file.explode(attachments[])[].file_extension eq "ics"
file.explode(attachments[])[].scan.strings.raw regex_match "[\\x{E0000}-\\x{E007F}\\x{E0100}-\\x{E01EF}\\x{2062}\\x{2064}]{8,}"
or
any(attachments)
attachments.content_type eq "text/calendar"
body.current_thread.text regex_match "(calendar|meeting|event|appointment)"
subject.subject regex_match "(calendar|meeting|event|appointment)"
any(attachments)
attachments.file_extension eq "ics"
not
subject.is_reply eq "true"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match value:"(calendar|meeting|event|appointment)" |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match value:"(calendar|meeting|event|appointment)" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Calendar invite from recently registered domain
#Detects calendar invites (.ics files) from organizers using domains registered within the last 90 days, which may indicate suspicious or malicious calendar invitations.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Callback Phishing |
| Tactics and techniques | Evasion, ICS Phishing, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) > 0
and all(attachments, .content_type in ("text/calendar", "application/ics"))
and any(attachments,
any(file.explode(.),
any(.scan.ics.calendars,
any(.components,
any(.organizers,
network.whois(.mailbox.email.domain).days_old < 90
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects calendar invites (.ics files) from organizers using domains registered within the last 90 days, which may indicate suspicious or malicious calendar invitations.
- inbound message
- length(attachments) > 0
all of
attachmentswhere:- .content_type in ('text/calendar', 'application/ics')
any of
attachmentswhere:any of
file.explode(.)where:any of
.scan.ics.calendarswhere:any of
.componentswhere:any of
.organizerswhere:- network.whois(.mailbox.email.domain).days_old < 90
Inspects: attachments[].content_type, type.inbound. Sensors: file.explode, network.whois.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | member | text/calendar |
attachments[].content_type | member | application/ics |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.explode(attachments))
any(file.explode(attachments).scan.ics.calendars)
any(file.explode(attachments).scan.ics.calendars.components)
any(file.explode(attachments).scan.ics.calendars.components.organizers)
network.whois func_call "network.whois(file.explode(attachments[])[].scan.ics.calendars[].components[].organizers[].mailbox.email.domain).days_old < 90"
attachments length_compare "0"
type.inbound eq "true"
macro "all(attachments)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Calendar invite with Google redirect and invoice request
#Detects calendar file attachments containing Google redirect URLs in the location field combined with invoice-related language in the message body.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, BEC/Fraud |
| Tactics and techniques | ICS Phishing, Open redirect, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ('ics')
or .content_type in ("application/ics", "text/calendar")
)
and regex.icontains(file.parse_text(.).text,
'LOCATION[^:]*:.{1,300}google\.com/url'
)
)
and any(ml.nlu_classifier(body.current_thread.text).topics,
.name == "Request to View Invoice" and .confidence == "high"
)
Detection logic
Scope: inbound message.
Detects calendar file attachments containing Google redirect URLs in the location field combined with invoice-related language in the message body.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('ics')
- .content_type in ('application/ics', 'text/calendar')
- file.parse_text(.).text matches 'LOCATION[^:]*:.{1,300}google\\.com/url'
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name is 'Request to View Invoice'
- .confidence is 'high'
Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, type.inbound. Sensors: file.parse_text, ml.nlu_classifier, regex.icontains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
regex.icontains | regex | LOCATION[^:]*:.{1,300}google\.com/url |
ml.nlu_classifier(body.current_thread.text).topics[].name | equals | Request to View Invoice |
ml.nlu_classifier(body.current_thread.text).topics[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
file.parse_text(attachments[]).text regex_match "LOCATION[^:]*:.{1,300}google\\.com/url"
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Calendar invite with suspicious link leading to an open redirect
#Calendar invite contains a link to either a free file host or free subdomain host, and the resulting webpage contains another link to an open redirect.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Spam |
| Tactics and techniques | Free email provider, Free file host, Free subdomain host, ICS Phishing, Open redirect |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension == "ics"
or .content_type in ("application/ics", "text/calendar")
)
and any(file.explode(.),
any(.scan.url.urls,
(
.domain.domain in $free_file_hosts
or (
.domain.root_domain in $free_subdomain_hosts
and .domain.subdomain is not null
and not (
strings.ends_with(.url, "jpeg")
or strings.ends_with(.url, "png")
)
and .domain.subdomain != "www"
)
)
and any(ml.link_analysis(.).final_dom.links,
any(.href_url.rewrite.encoders,
strings.icontains(., "open_redirect")
)
)
)
)
)
// 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
)
)
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
Calendar invite contains a link to either a free file host or free subdomain host, and the resulting webpage contains another link to an open redirect.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'ics'
- .content_type in ('application/ics', 'text/calendar')
any of
file.explode(.)where:any of
.scan.url.urlswhere all hold:any of:
- .domain.domain in $free_file_hosts
all of:
- .domain.root_domain in $free_subdomain_hosts
- .domain.subdomain is set
none of:
- .url ends with 'jpeg'
- .url ends with 'png'
- .domain.subdomain is not 'www'
any of
ml.link_analysis(.).final_dom.linkswhere:any of
.href_url.rewrite.encoderswhere:- . contains 'open_redirect'
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
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, headers.hops, headers.hops[].authentication_results.dmarc, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.ends_with, strings.icontains, strings.ilike. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
strings.icontains | substring | open_redirect |
strings.ilike | substring | *fail |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
or
and
not
or
file.explode(attachments[])[].scan.url.urls[].url ends_with "jpeg"
file.explode(attachments[])[].scan.url.urls[].url ends_with "png"
file.explode(attachments[])[].scan.url.urls[].domain.subdomain is_not_null
file.explode(attachments[])[].scan.url.urls[].domain.subdomain ne "www"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain in free_file_hosts"
any(ml.link_analysis(file.explode(attachments).scan.url.urls).final_dom.links)
any(ml.link_analysis(file.explode(attachments).scan.url.urls).final_dom.links.href_url.rewrite.encoders)
ml.link_analysis(file.explode(attachments).scan.url.urls).final_dom.links.href_url.rewrite.encoders contains "open_redirect"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
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"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Callback phishing solicitation via image file
#A fraudulent invoice/receipt found in an image attachment. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Callback Phishing |
| Tactics and techniques | Evasion, Free email provider, Out of band pivot, Social engineering, Image as content |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
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 (subject.is_reply and headers.in_reply_to is not null)
and not profile.by_sender_email().prevalence == "common"
and (
sender.email.domain.root_domain in $free_email_providers
or sender.email.domain.root_domain in ("onmicrosoft.com")
or (
(
length(recipients.to) == 0
or all(recipients.to, .display_name == "Undisclosed recipients")
)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
)
)
and any(attachments,
// exclude images taken with mobile cameras and screenshots from android
.file_type in $file_types_images
and (
any(file.explode(.),
not any(.scan.exiftool.fields,
.key == "Model"
or (
.key == "Software"
and strings.starts_with(.value, "Android")
)
)
// exclude images taken with mobile cameras and screenshots from Apple
and not any(.scan.exiftool.fields,
.key == "DeviceManufacturer"
and .value == "Apple Computer Inc."
)
and not any(.scan.exiftool.fields,
.key == "UserComment" and .value == "Screenshot"
)
// 4 of the following strings are found
and 4 of (
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
strings.icontains(.scan.ocr.raw, "purchase"),
strings.icontains(.scan.ocr.raw, "payment"),
strings.icontains(.scan.ocr.raw, "transaction"),
strings.icontains(.scan.ocr.raw, "subscription"),
strings.icontains(.scan.ocr.raw, "antivirus"),
strings.icontains(.scan.ocr.raw, "order"),
strings.icontains(.scan.ocr.raw, "support"),
strings.icontains(.scan.ocr.raw, "help line"),
strings.icontains(.scan.ocr.raw, "receipt"),
strings.icontains(.scan.ocr.raw, "invoice"),
strings.icontains(.scan.ocr.raw, "call"),
strings.icontains(.scan.ocr.raw, "helpdesk"),
strings.icontains(.scan.ocr.raw, "cancel"),
strings.icontains(.scan.ocr.raw, "renew"),
strings.icontains(.scan.ocr.raw, "refund"),
regex.icontains(.scan.ocr.raw, "(?:reach|contact) us at"),
strings.icontains(.scan.ocr.raw, "+1"),
strings.icontains(.scan.ocr.raw, "amount"),
strings.icontains(.scan.ocr.raw, "charged"),
strings.icontains(.scan.ocr.raw, "crypto"),
strings.icontains(.scan.ocr.raw, "wallet address"),
regex.icontains(.scan.ocr.raw, '\$\d{3}\.\d{2}\b'),
regex.icontains(.scan.ocr.raw,
'\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
'\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
),
)
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
and regex.icontains(.scan.ocr.raw,
'(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
)
)
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
or any(ml.logo_detect(.).brands,
.name in (
"PayPal",
"Norton",
"GeekSquad",
"Ebay",
"McAfee",
"AT&T"
)
)
)
)
Detection logic
Scope: inbound message.
A fraudulent invoice/receipt found in an image attachment. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.
- inbound message
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
all of:
- subject.is_reply
- headers.in_reply_to is set
not:
- profile.by_sender_email().prevalence is 'common'
any of:
- sender.email.domain.root_domain in $free_email_providers
- sender.email.domain.root_domain in ('onmicrosoft.com')
all of:
any of:
- length(recipients.to) is 0
all of
recipients.towhere:- .display_name is 'Undisclosed recipients'
- length(recipients.cc) is 0
- length(recipients.bcc) is 0
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of:
any of
file.explode(.)where all hold:not:
any of
.scan.exiftool.fieldswhere any holds:- .key is 'Model'
all of:
- .key is 'Software'
- .value starts with 'Android'
not:
any of
.scan.exiftool.fieldswhere all hold:- .key is 'DeviceManufacturer'
- .value is 'Apple Computer Inc.'
not:
any of
.scan.exiftool.fieldswhere all hold:- .key is 'UserComment'
- .value is 'Screenshot'
at least 4 of:
- .scan.ocr.raw contains 'purchase'
- .scan.ocr.raw contains 'payment'
- .scan.ocr.raw contains 'transaction'
- .scan.ocr.raw contains 'subscription'
- .scan.ocr.raw contains 'antivirus'
- .scan.ocr.raw contains 'order'
- .scan.ocr.raw contains 'support'
- .scan.ocr.raw contains 'help line'
- .scan.ocr.raw contains 'receipt'
- .scan.ocr.raw contains 'invoice'
- .scan.ocr.raw contains 'call'
- .scan.ocr.raw contains 'helpdesk'
- .scan.ocr.raw contains 'cancel'
- .scan.ocr.raw contains 'renew'
- .scan.ocr.raw contains 'refund'
- .scan.ocr.raw matches '(?:reach|contact) us at'
- .scan.ocr.raw contains '+1'
- .scan.ocr.raw contains 'amount'
- .scan.ocr.raw contains 'charged'
- .scan.ocr.raw contains 'crypto'
- .scan.ocr.raw contains 'wallet address'
- .scan.ocr.raw matches '\\$\\d{3}\\.\\d{2}\\b'
.scan.ocr.raw matches any of 2 patterns
\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
- .scan.ocr.raw matches '(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
any of
ml.logo_detect(.).brandswhere:- .name in ('PayPal', 'Norton', 'GeekSquad', 'Ebay', 'McAfee', 'AT&T')
Inspects: attachments[].file_type, headers.in_reply_to, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, sender.email.domain.root_domain, subject.is_reply, type.inbound. Sensors: file.explode, ml.logo_detect, profile.by_sender, profile.by_sender_email, regex.icontains, strings.icontains, strings.starts_with. Reference lists: $file_types_images, $free_email_providers.
Indicators matched (33)
| Field | Match | Value |
|---|---|---|
sender.email.domain.root_domain | member | onmicrosoft.com |
recipients.to[].display_name | equals | Undisclosed recipients |
strings.icontains | substring | purchase |
strings.icontains | substring | payment |
strings.icontains | substring | transaction |
strings.icontains | substring | subscription |
strings.icontains | substring | antivirus |
strings.icontains | substring | order |
strings.icontains | substring | support |
strings.icontains | substring | help line |
strings.icontains | substring | receipt |
strings.icontains | substring | invoice |
21 more
strings.icontains | substring | call |
strings.icontains | substring | helpdesk |
strings.icontains | substring | cancel |
strings.icontains | substring | renew |
strings.icontains | substring | refund |
regex.icontains | regex | (?:reach|contact) us at |
strings.icontains | substring | +1 |
strings.icontains | substring | amount |
strings.icontains | substring | charged |
strings.icontains | substring | crypto |
strings.icontains | substring | wallet address |
regex.icontains | regex | \$\d{3}\.\d{2}\b |
regex.icontains | regex | \+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4} |
regex.icontains | regex | \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4} |
regex.icontains | regex | (p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t) |
ml.logo_detect(attachments[]).brands[].name | member | PayPal |
ml.logo_detect(attachments[]).brands[].name | member | Norton |
ml.logo_detect(attachments[]).brands[].name | member | GeekSquad |
ml.logo_detect(attachments[]).brands[].name | member | Ebay |
ml.logo_detect(attachments[]).brands[].name | member | McAfee |
ml.logo_detect(attachments[]).brands[].name | member | AT&T |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
any(file.explode(attachments))
and
not
any(file.explode(attachments).scan.exiftool.fields)
or
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Software"
file.explode(attachments[])[].scan.exiftool.fields[].value starts_with "Android"
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Model"
not
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "DeviceManufacturer"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "Apple Computer Inc."
not
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "UserComment"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "Screenshot"
or
file.explode(attachments[])[].scan.ocr.raw contains "+1"
file.explode(attachments[])[].scan.ocr.raw contains "amount"
file.explode(attachments[])[].scan.ocr.raw contains "antivirus"
file.explode(attachments[])[].scan.ocr.raw contains "call"
file.explode(attachments[])[].scan.ocr.raw contains "cancel"
file.explode(attachments[])[].scan.ocr.raw contains "charged"
file.explode(attachments[])[].scan.ocr.raw contains "crypto"
file.explode(attachments[])[].scan.ocr.raw contains "help line"
file.explode(attachments[])[].scan.ocr.raw contains "helpdesk"
file.explode(attachments[])[].scan.ocr.raw contains "invoice"
file.explode(attachments[])[].scan.ocr.raw contains "order"
file.explode(attachments[])[].scan.ocr.raw contains "payment"
file.explode(attachments[])[].scan.ocr.raw contains "purchase"
file.explode(attachments[])[].scan.ocr.raw contains "receipt"
file.explode(attachments[])[].scan.ocr.raw contains "refund"
file.explode(attachments[])[].scan.ocr.raw contains "renew"
file.explode(attachments[])[].scan.ocr.raw contains "subscription"
file.explode(attachments[])[].scan.ocr.raw contains "support"
file.explode(attachments[])[].scan.ocr.raw contains "transaction"
file.explode(attachments[])[].scan.ocr.raw contains "wallet address"
file.explode(attachments[])[].scan.ocr.raw regex_match "(?:reach|contact) us at"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\$\\d{3}\\.\\d{2}\\b"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\+?([ilo0-9]{1,2})?\\s?\\(?\\d{3}\\)?[\\s\\.\\-⋅]{0,5}[ilo0-9]{3}[\\s\\.\\-⋅]{0,5}[ilo0-9]{4}"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\+?([ilo0-9]{1}.)?\\(?[ilo0-9]{3}?\\)?.[ilo0-9]{3}.?[ilo0-9]{4}"
file.explode(attachments[])[].scan.ocr.raw regex_match "(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name in ["AT&T", "Ebay", "GeekSquad", "McAfee", "Norton", "PayPal"]
macro "attachments[].file_type in file_types_images"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
and
or
recipients.to length_compare "0"
macro "all(recipients.to)"
recipients.bcc length_compare "0"
recipients.cc length_compare "0"
sender.email.domain.root_domain eq "onmicrosoft.com"
macro "sender.email.domain.root_domain in free_email_providers"
not
and
headers.in_reply_to is_not_null
subject.is_reply eq "true"
not
profile.by_sender_email func_call "profile.by_sender_email().prevalence == common"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.in_reply_to | is_not_null | excludes:headers.in_reply_to | |
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.email.domain.root_domain | in |
| field:"sender.email.domain.root_domain" kind:in value:"onmicrosoft.com" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Callback phishing solicitation via pdf file
#A fraudulent invoice/receipt found in a pdf attachment. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Callback Phishing |
| Tactics and techniques | Evasion, Free email provider, Out of band pivot, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
not profile.by_sender().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
// single attachment
and length(attachments) == 1
// sender is freemail
and (
sender.email.domain.root_domain in $free_email_providers
// the sender is a common service, which has likely been sent through a DL
or (
sender.email.domain.root_domain in $tranco_50k
and all(recipients.to, .email.domain.domain not in $org_domains)
)
)
// negate ML matches to "Professional and Career Development" - tuning resume FPs
and not any(ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics,
.name == "Professional and Career Development"
and .confidence == "high"
)
and not any(attachments,
.file_type == 'pdf'
and any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name == "Professional and Career Development"
and .confidence == "high"
)
)
)
// the attachment is a pdf with less than 3 pages, and at least 60 ocr chars
and any(attachments,
(
.file_extension == "pdf"
// get the length of the attached pdf
and any(file.explode(.),
.depth == 0
and .scan.exiftool.page_count < 3
and (
not (
strings.istarts_with(.scan.exiftool.producer,
"Aspose.Words for Java"
)
and (
.scan.exiftool.creator == "Anusha T"
or any(.scan.exiftool.fields,
.key == "Author" and .value == "Anusha T"
)
)
)
or .scan.exiftool.producer is null
or .scan.exiftool.creator is null
)
)
// check that any _single_ result in the file.explode matches these conditions
// a second file.explode is required because the OCR is generated at a different depth within
// the file.explode results
and (
any(file.explode(.),
length(.scan.ocr.raw) > 60
// 4 of the following strings are found
and 4 of (
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
strings.icontains(.scan.ocr.raw, "purchase"),
strings.icontains(.scan.ocr.raw, "payment"),
strings.icontains(.scan.ocr.raw, "transaction"),
strings.icontains(.scan.ocr.raw, "subscription"),
strings.icontains(.scan.ocr.raw, "antivirus"),
strings.icontains(.scan.ocr.raw, "order"),
strings.icontains(.scan.ocr.raw, "support"),
strings.icontains(.scan.ocr.raw, "help line"),
strings.icontains(.scan.ocr.raw, "receipt"),
strings.icontains(.scan.ocr.raw, "invoice"),
strings.icontains(.scan.ocr.raw, "call"),
strings.icontains(.scan.ocr.raw, "helpdesk"),
strings.icontains(.scan.ocr.raw, "cancel"),
strings.icontains(.scan.ocr.raw, "renew"),
strings.icontains(.scan.ocr.raw, "refund"),
regex.icontains(.scan.ocr.raw, "(?:reach|contact) us at"),
strings.icontains(.scan.ocr.raw, "+1"),
strings.icontains(.scan.ocr.raw, "amount"),
strings.icontains(.scan.ocr.raw, "charged"),
strings.icontains(.scan.ocr.raw, "crypto"),
strings.icontains(.scan.ocr.raw, "wallet address"),
regex.icontains(.scan.ocr.raw, '\$\d{3}\.\d{2}\b'),
regex.icontains(.scan.ocr.raw,
'(\+[ilo0-9]|1.(\()?[ilo0-9]{3}(\))?\D[ilo0-9]{3}\D[ilo0-9]{4})',
'\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
),
)
and (
// this section is synced with attachment_callback_phish_with_img.yml and body_callback_phishing_no_attachment.yml
regex.icontains(.scan.ocr.raw,
'(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
)
// suspicious attachment name from the attachment object not file.explode() output
or regex.icontains(..file_name, 'INV(?:_|\s)?\d+(.pdf)$')
)
// Negate bank statements
and not (
2 of (
strings.icontains(.scan.ocr.raw, "opening balance"),
strings.icontains(.scan.ocr.raw, "closing balance"),
strings.icontains(.scan.ocr.raw, "direct debit"),
strings.icontains(.scan.ocr.raw, "interest"),
strings.icontains(.scan.ocr.raw, "account balance"),
)
)
)
// this section is synced with attachment_callback_phish_with_img.yml and body_callback_phishing_no_attachment.yml
or any(ml.logo_detect(.).brands,
.name in (
"PayPal",
"Norton",
"GeekSquad",
"Ebay",
"McAfee",
"AT&T"
)
)
)
)
)
and (
(
(length(headers.references) > 0 or headers.in_reply_to is null)
and not (
(
strings.istarts_with(subject.subject, "RE:")
or strings.istarts_with(subject.subject, "RES:")
or strings.istarts_with(subject.subject, "R:")
or strings.istarts_with(subject.subject, "ODG:")
or strings.istarts_with(subject.subject, "答复:")
or strings.istarts_with(subject.subject, "AW:")
or strings.istarts_with(subject.subject, "TR:")
or strings.istarts_with(subject.subject, "FWD:")
or regex.imatch(subject.subject,
'(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
)
)
)
)
or (length(headers.references) == 0 or length(body.current_thread.text) < 10)
)
Detection logic
Scope: inbound message.
A fraudulent invoice/receipt found in a pdf attachment. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.
- inbound message
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
- length(attachments) is 1
any of:
- sender.email.domain.root_domain in $free_email_providers
all of:
- sender.email.domain.root_domain in $tranco_50k
all of
recipients.towhere:- .email.domain.domain not in $org_domains
not:
any of
ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topicswhere all hold:- .name is 'Professional and Career Development'
- .confidence is 'high'
not:
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where:any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere all hold:- .name is 'Professional and Career Development'
- .confidence is 'high'
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where all hold:- .depth is 0
- .scan.exiftool.page_count < 3
any of:
not:
all of:
- .scan.exiftool.producer starts with 'Aspose.Words for Java'
any of:
- .scan.exiftool.creator is 'Anusha T'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'Author'
- .value is 'Anusha T'
- .scan.exiftool.producer is missing
- .scan.exiftool.creator is missing
any of:
any of
file.explode(.)where all hold:- length(.scan.ocr.raw) > 60
at least 4 of:
- .scan.ocr.raw contains 'purchase'
- .scan.ocr.raw contains 'payment'
- .scan.ocr.raw contains 'transaction'
- .scan.ocr.raw contains 'subscription'
- .scan.ocr.raw contains 'antivirus'
- .scan.ocr.raw contains 'order'
- .scan.ocr.raw contains 'support'
- .scan.ocr.raw contains 'help line'
- .scan.ocr.raw contains 'receipt'
- .scan.ocr.raw contains 'invoice'
- .scan.ocr.raw contains 'call'
- .scan.ocr.raw contains 'helpdesk'
- .scan.ocr.raw contains 'cancel'
- .scan.ocr.raw contains 'renew'
- .scan.ocr.raw contains 'refund'
- .scan.ocr.raw matches '(?:reach|contact) us at'
- .scan.ocr.raw contains '+1'
- .scan.ocr.raw contains 'amount'
- .scan.ocr.raw contains 'charged'
- .scan.ocr.raw contains 'crypto'
- .scan.ocr.raw contains 'wallet address'
- .scan.ocr.raw matches '\\$\\d{3}\\.\\d{2}\\b'
.scan.ocr.raw matches any of 2 patterns
(\+[ilo0-9]|1.(\()?[ilo0-9]{3}(\))?\D[ilo0-9]{3}\D[ilo0-9]{4})\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
any of:
- .scan.ocr.raw matches '(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
- .file_name matches 'INV(?:_|\\s)?\\d+(.pdf)$'
not:
at least 2 of 5: .scan.ocr.raw contains any of 5 patterns
opening balanceclosing balancedirect debitinterestaccount balance
any of
ml.logo_detect(.).brandswhere:- .name in ('PayPal', 'Norton', 'GeekSquad', 'Ebay', 'McAfee', 'AT&T')
any of:
all of:
any of:
- length(headers.references) > 0
- headers.in_reply_to is missing
none of:
- subject.subject starts with 'RE:'
- subject.subject starts with 'RES:'
- subject.subject starts with 'R:'
- subject.subject starts with 'ODG:'
- subject.subject starts with '答复:'
- subject.subject starts with 'AW:'
- subject.subject starts with 'TR:'
- subject.subject starts with 'FWD:'
- subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?|automat.*)\\s?:.*'
any of:
- length(headers.references) is 0
- length(body.current_thread.text) < 10
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.html.display_text, body.plain.raw, headers.in_reply_to, headers.references, recipients.to, recipients.to[].email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, regex.imatch, strings.icontains, strings.istarts_with. Reference lists: $free_email_providers, $org_domains, $tranco_50k.
Indicators matched (33)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
strings.icontains | substring | purchase |
strings.icontains | substring | payment |
strings.icontains | substring | transaction |
strings.icontains | substring | subscription |
strings.icontains | substring | antivirus |
strings.icontains | substring | order |
strings.icontains | substring | support |
strings.icontains | substring | help line |
strings.icontains | substring | receipt |
strings.icontains | substring | invoice |
strings.icontains | substring | call |
21 more
strings.icontains | substring | helpdesk |
strings.icontains | substring | cancel |
strings.icontains | substring | renew |
strings.icontains | substring | refund |
regex.icontains | regex | (?:reach|contact) us at |
strings.icontains | substring | +1 |
strings.icontains | substring | amount |
strings.icontains | substring | charged |
strings.icontains | substring | crypto |
strings.icontains | substring | wallet address |
regex.icontains | regex | \$\d{3}\.\d{2}\b |
regex.icontains | regex | (\+[ilo0-9]|1.(\()?[ilo0-9]{3}(\))?\D[ilo0-9]{3}\D[ilo0-9]{4}) |
regex.icontains | regex | \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4} |
regex.icontains | regex | (p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t) |
regex.icontains | regex | INV(?:_|\s)?\d+(.pdf)$ |
ml.logo_detect(attachments[]).brands[].name | member | PayPal |
ml.logo_detect(attachments[]).brands[].name | member | Norton |
ml.logo_detect(attachments[]).brands[].name | member | GeekSquad |
ml.logo_detect(attachments[]).brands[].name | member | Ebay |
ml.logo_detect(attachments[]).brands[].name | member | McAfee |
ml.logo_detect(attachments[]).brands[].name | member | AT&T |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
not
and
or
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Author"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "Anusha T"
file.explode(attachments[])[].scan.exiftool.creator eq "Anusha T"
file.explode(attachments[])[].scan.exiftool.producer starts_with "Aspose.Words for Java"
file.explode(attachments[])[].scan.exiftool.creator is_null
file.explode(attachments[])[].scan.exiftool.producer is_null
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.exiftool.page_count lt "3"
or
any(file.explode(attachments))
and
not
or
file.explode(attachments[])[].scan.ocr.raw contains "account balance"
file.explode(attachments[])[].scan.ocr.raw contains "closing balance"
file.explode(attachments[])[].scan.ocr.raw contains "direct debit"
file.explode(attachments[])[].scan.ocr.raw contains "interest"
file.explode(attachments[])[].scan.ocr.raw contains "opening balance"
or
attachments.file_name regex_match "INV(?:_|\\s)?\\d+(.pdf)$"
file.explode(attachments[])[].scan.ocr.raw regex_match "(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)"
or
file.explode(attachments[])[].scan.ocr.raw contains "+1"
file.explode(attachments[])[].scan.ocr.raw contains "amount"
file.explode(attachments[])[].scan.ocr.raw contains "antivirus"
file.explode(attachments[])[].scan.ocr.raw contains "call"
file.explode(attachments[])[].scan.ocr.raw contains "cancel"
file.explode(attachments[])[].scan.ocr.raw contains "charged"
file.explode(attachments[])[].scan.ocr.raw contains "crypto"
file.explode(attachments[])[].scan.ocr.raw contains "help line"
file.explode(attachments[])[].scan.ocr.raw contains "helpdesk"
file.explode(attachments[])[].scan.ocr.raw contains "invoice"
file.explode(attachments[])[].scan.ocr.raw contains "order"
file.explode(attachments[])[].scan.ocr.raw contains "payment"
file.explode(attachments[])[].scan.ocr.raw contains "purchase"
file.explode(attachments[])[].scan.ocr.raw contains "receipt"
file.explode(attachments[])[].scan.ocr.raw contains "refund"
file.explode(attachments[])[].scan.ocr.raw contains "renew"
file.explode(attachments[])[].scan.ocr.raw contains "subscription"
file.explode(attachments[])[].scan.ocr.raw contains "support"
file.explode(attachments[])[].scan.ocr.raw contains "transaction"
file.explode(attachments[])[].scan.ocr.raw contains "wallet address"
file.explode(attachments[])[].scan.ocr.raw regex_match "(?:reach|contact) us at"
file.explode(attachments[])[].scan.ocr.raw regex_match "(\\+[ilo0-9]|1.(\\()?[ilo0-9]{3}(\\))?\\D[ilo0-9]{3}\\D[ilo0-9]{4})"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\$\\d{3}\\.\\d{2}\\b"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\+?([ilo0-9]{1,2})?\\s?\\(?\\d{3}\\)?[\\s\\.\\-⋅]{0,5}[ilo0-9]{3}[\\s\\.\\-⋅]{0,5}[ilo0-9]{4}"
file.explode(attachments[])[].scan.ocr.raw length_compare "60"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name in ["AT&T", "Ebay", "GeekSquad", "McAfee", "Norton", "PayPal"]
attachments.file_extension eq "pdf"
not
any(attachments)
and
any(file.explode(attachments))
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).topics)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence eq "high"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name eq "Professional and Career Development"
attachments.file_type eq "pdf"
or
and
not
or
subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?|automat.*)\\s?:.*"
subject.subject starts_with "AW:"
subject.subject starts_with "FWD:"
subject.subject starts_with "ODG:"
subject.subject starts_with "R:"
subject.subject starts_with "RE:"
subject.subject starts_with "RES:"
subject.subject starts_with "TR:"
subject.subject starts_with "答复:"
or
headers.in_reply_to is_null
headers.references length_compare "0"
body.current_thread.text length_compare "10"
headers.references length_compare "0"
not
any(ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics)
and
ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics.confidence eq "high"
ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics.name eq "Professional and Career Development"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
and
macro "all(recipients.to)"
macro "sender.email.domain.root_domain in tranco_50k"
macro "sender.email.domain.root_domain in free_email_providers"
attachments length_compare "1"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments | |
ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics | array_any | excludes:ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Callback phishing solicitation via text-based file
#Callback Phishing via a text-based file attachment and a short body and subject from an unknown sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Callback Phishing |
| Tactics and techniques | Evasion, Out of band pivot, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(subject.subject) <= 10
// there are no links, all the links are to aka.ms, or an extraction from a warning banner that match the senders domain
and (
length(body.links) == 0
or length(filter(body.links,
(
.display_text is null
and .display_url.url == sender.email.domain.root_domain
)
or .href_url.domain.domain == "aka.ms"
or network.whois(.display_url.domain).days_old < 30
)
) == length(body.links)
)
and (body.current_thread.text is null or length(body.current_thread.text) < 50)
and 0 < length(attachments) < 4
and any(attachments,
(
.content_type == "text/plain"
or .file_type in ("doc", "docx", "xls", "xlsx")
)
and any(file.explode(.),
(.depth == 0 or .flavors.mime == "text/plain")
// 4 of the following strings are found
and 4 of (
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
strings.icontains(.scan.strings.raw, "purchase"),
strings.icontains(.scan.strings.raw, "payment"),
strings.icontains(.scan.strings.raw, "transaction"),
strings.icontains(.scan.strings.raw, "subscription"),
strings.icontains(.scan.strings.raw, "antivirus"),
strings.icontains(.scan.strings.raw, "order"),
strings.icontains(.scan.strings.raw, "support"),
strings.icontains(.scan.strings.raw, "help line"),
strings.icontains(.scan.strings.raw, "receipt"),
strings.icontains(.scan.strings.raw, "invoice"),
strings.icontains(.scan.strings.raw, "call"),
strings.icontains(.scan.strings.raw, "helpdesk"),
strings.icontains(.scan.strings.raw, "cancel"),
strings.icontains(.scan.strings.raw, "renew"),
strings.icontains(.scan.strings.raw, "refund"),
regex.icontains(.scan.strings.raw, "(?:reach|contact) us at"),
strings.icontains(.scan.strings.raw, "+1"),
strings.icontains(.scan.strings.raw, "amount"),
strings.icontains(.scan.strings.raw, "charged"),
strings.icontains(.scan.strings.raw, "crypto"),
strings.icontains(.scan.strings.raw, "wallet address"),
regex.icontains(.scan.strings.raw, '\$\d{3}\.\d{2}\b'),
regex.icontains(.scan.strings.raw,
'\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
'\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
),
)
// this section is synced with attachment_callback_phish_with_pdf.yml and body_callback_phishing_no_attachment.yml
and regex.icontains(.scan.strings.raw,
'(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t|quickbooks)'
)
)
)
and profile.by_sender().prevalence != "common"
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_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.
Callback Phishing via a text-based file attachment and a short body and subject from an unknown sender.
- inbound message
- length(subject.subject) ≤ 10
any of:
- length(body.links) is 0
- length(filter(body.links, .display_text is null and .display_url.url == sender.email.domain.root_domain or .href_url.domain.domain == 'aka.ms' or network.whois(.display_url.domain).days_old < 30)) is length(body.links)
any of:
- body.current_thread.text is missing
- length(body.current_thread.text) < 50
all of:
- length(attachments) > 0
- length(attachments) < 4
any of
attachmentswhere all hold:any of:
- .content_type is 'text/plain'
- .file_type in ('doc', 'docx', 'xls', 'xlsx')
any of
file.explode(.)where all hold:any of:
- .depth is 0
- .flavors.mime is 'text/plain'
at least 4 of:
- .scan.strings.raw contains 'purchase'
- .scan.strings.raw contains 'payment'
- .scan.strings.raw contains 'transaction'
- .scan.strings.raw contains 'subscription'
- .scan.strings.raw contains 'antivirus'
- .scan.strings.raw contains 'order'
- .scan.strings.raw contains 'support'
- .scan.strings.raw contains 'help line'
- .scan.strings.raw contains 'receipt'
- .scan.strings.raw contains 'invoice'
- .scan.strings.raw contains 'call'
- .scan.strings.raw contains 'helpdesk'
- .scan.strings.raw contains 'cancel'
- .scan.strings.raw contains 'renew'
- .scan.strings.raw contains 'refund'
- .scan.strings.raw matches '(?:reach|contact) us at'
- .scan.strings.raw contains '+1'
- .scan.strings.raw contains 'amount'
- .scan.strings.raw contains 'charged'
- .scan.strings.raw contains 'crypto'
- .scan.strings.raw contains 'wallet address'
- .scan.strings.raw matches '\\$\\d{3}\\.\\d{2}\\b'
.scan.strings.raw matches any of 2 patterns
\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
- .scan.strings.raw matches '(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t|quickbooks)'
- profile.by_sender().prevalence is not 'common'
not:
- profile.by_sender().solicited
not:
- profile.by_sender().any_messages_benign
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].content_type, attachments[].file_type, body.current_thread.text, body.links, body.links[].display_text, body.links[].display_url.domain, body.links[].display_url.url, body.links[].href_url.domain.domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, network.whois, profile.by_sender, regex.icontains, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (32)
| Field | Match | Value |
|---|---|---|
body.links[].href_url.domain.domain | equals | aka.ms |
attachments[].content_type | equals | text/plain |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
attachments[].file_type | member | xls |
attachments[].file_type | member | xlsx |
file.explode(attachments[])[].flavors.mime | equals | text/plain |
strings.icontains | substring | purchase |
strings.icontains | substring | payment |
strings.icontains | substring | transaction |
strings.icontains | substring | subscription |
strings.icontains | substring | antivirus |
20 more
strings.icontains | substring | order |
strings.icontains | substring | support |
strings.icontains | substring | help line |
strings.icontains | substring | receipt |
strings.icontains | substring | invoice |
strings.icontains | substring | call |
strings.icontains | substring | helpdesk |
strings.icontains | substring | cancel |
strings.icontains | substring | renew |
strings.icontains | substring | refund |
regex.icontains | regex | (?:reach|contact) us at |
strings.icontains | substring | +1 |
strings.icontains | substring | amount |
strings.icontains | substring | charged |
strings.icontains | substring | crypto |
strings.icontains | substring | wallet address |
regex.icontains | regex | \$\d{3}\.\d{2}\b |
regex.icontains | regex | \+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4} |
regex.icontains | regex | \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4} |
regex.icontains | regex | (p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t|quickbooks) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].flavors.mime eq "text/plain"
or
file.explode(attachments[])[].scan.strings.raw contains "+1"
file.explode(attachments[])[].scan.strings.raw contains "amount"
file.explode(attachments[])[].scan.strings.raw contains "antivirus"
file.explode(attachments[])[].scan.strings.raw contains "call"
file.explode(attachments[])[].scan.strings.raw contains "cancel"
file.explode(attachments[])[].scan.strings.raw contains "charged"
file.explode(attachments[])[].scan.strings.raw contains "crypto"
file.explode(attachments[])[].scan.strings.raw contains "help line"
file.explode(attachments[])[].scan.strings.raw contains "helpdesk"
file.explode(attachments[])[].scan.strings.raw contains "invoice"
file.explode(attachments[])[].scan.strings.raw contains "order"
file.explode(attachments[])[].scan.strings.raw contains "payment"
file.explode(attachments[])[].scan.strings.raw contains "purchase"
file.explode(attachments[])[].scan.strings.raw contains "receipt"
file.explode(attachments[])[].scan.strings.raw contains "refund"
file.explode(attachments[])[].scan.strings.raw contains "renew"
file.explode(attachments[])[].scan.strings.raw contains "subscription"
file.explode(attachments[])[].scan.strings.raw contains "support"
file.explode(attachments[])[].scan.strings.raw contains "transaction"
file.explode(attachments[])[].scan.strings.raw contains "wallet address"
file.explode(attachments[])[].scan.strings.raw regex_match "(?:reach|contact) us at"
file.explode(attachments[])[].scan.strings.raw regex_match "\\$\\d{3}\\.\\d{2}\\b"
file.explode(attachments[])[].scan.strings.raw regex_match "\\+?([ilo0-9]{1,2})?\\s?\\(?\\d{3}\\)?[\\s\\.\\-⋅]{0,5}[ilo0-9]{3}[\\s\\.\\-⋅]{0,5}[ilo0-9]{4}"
file.explode(attachments[])[].scan.strings.raw regex_match "\\+?([ilo0-9]{1}.)?\\(?[ilo0-9]{3}?\\)?.[ilo0-9]{3}.?[ilo0-9]{4}"
file.explode(attachments[])[].scan.strings.raw regex_match "(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t|quickbooks)"
or
attachments.content_type eq "text/plain"
attachments.file_type in ["doc", "docx", "xls", "xlsx"]
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 is_null
body.current_thread.text length_compare "50"
or
body.links length_compare "0"
length func_call "length(filter(body.links, .display_text is null and .display_url.url == sender.email.domain.root_domain or .href_url.domain.domain == 'aka.ms' or network.whois(.display_url.domain).days_old < 30)) == length(body.links)"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
not
profile.by_sender func_call "profile.by_sender().solicited"
attachments length_compare "0"
attachments length_compare "4"
profile.by_sender func_call "profile.by_sender().prevalence != common"
subject.subject length_compare "10"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Canva PDF with susupicious author metadata
#Detects inbound messages containing PDF attachments that were created using Canva but have author metadata containing '@proton.me', indicating potential service abuse where legitimate design tools are being misused in conjunction with privacy-focused email services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Free email provider, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
strings.icontains(beta.parse_exif(.).author, '@proton.me')
and beta.parse_exif(.).producer == 'Canva'
)
Detection logic
Scope: inbound message.
Detects inbound messages containing PDF attachments that were created using Canva but have author metadata containing '@proton.me', indicating potential service abuse where legitimate design tools are being misused in conjunction with privacy-focused email services.
- inbound message
any of
filter(attachments)where all hold:- beta.parse_exif(.).author contains '@proton.me'
- beta.parse_exif(.).producer is 'Canva'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | @proton.me |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).producer == Canva"
beta.parse_exif(filter(attachments)[]).author contains "@proton.me"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: cmd file extension
#Detects messages containing CMD (Command Prompt) batch files, either as direct attachments or within compressed archives. CMD files can execute arbitrary system commands and are commonly used to deliver malware or perform unauthorized system modifications.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) > 0
and any(attachments,
.file_extension =~ "cmd"
or (
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "cmd")
)
)
Detection logic
Scope: inbound message.
Detects messages containing CMD (Command Prompt) batch files, either as direct attachments or within compressed archives. CMD files can execute arbitrary system commands and are commonly used to deliver malware or perform unauthorized system modifications.
- inbound message
- length(attachments) > 0
any of
attachmentswhere any holds:- .file_extension is 'cmd'
all of:
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'cmd'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | cmd |
file.explode(attachments[])[].file_extension | equals | cmd |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "cmd"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.file_extension eq "cmd"
attachments length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Compensation review lure with QR code
#Detects PDF attachments containing compensation or payroll-themed content with QR codes from unsolicited or suspicious senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments, .content_type == "application/pdf" or .file_type == "pdf")
and (
// short or null message body
(
length(body.current_thread.text) < 500 or body.current_thread.text is null
)
// ignore disclaimers in body length calculation
or (
any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
.name == "disclaimer"
),
.text
),
(length(body.current_thread.text) - length(.)) < 500
)
)
)
)
and (
// attached PDF contains a compensation review themed lure with a QR code and suspicious indicators
any(attachments,
// add conditions for pdf attachment
(
regex.icontains(.file_name,
'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting'
)
// recipient email SLD in filename
or any(recipients.to,
strings.icontains(..file_name, .email.domain.sld)
and .email.domain.valid
)
or regex.icontains(beta.parse_exif(.).title,
'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting'
)
)
// add conditions for text and any QR code within the pdf attachment
and (
// conditions for QR code via text
any(file.explode(.),
any([.scan.strings.raw, .scan.ocr.raw],
regex.icontains(., 'scan|camera|review and sign')
and regex.icontains(., '\bQR\b|Q\.R\.|barcode')
)
)
or any(file.explode(.),
.scan.qr.type == "url" and .scan.qr.url.domain.valid
)
)
// conditions for text
and any(file.explode(.),
// review/change terms in file content
any([.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title],
(
regex.icontains(.,
'\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b'
)
)
)
or (
// recipient local_part in attachment body
any(recipients.to,
strings.contains(..scan.ocr.raw, .email.local_part)
)
and (
// NLU cred_theft disposition
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence != "low"
)
// suspicious topics
and any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name in (
"Benefit Enrollment",
"Financial Communications"
)
and .confidence != "low"
)
)
)
)
)
)
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
)
// account for spoofed sender domains
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.
Detects PDF attachments containing compensation or payroll-themed content with QR codes from unsolicited or suspicious senders.
- inbound message
all of:
any of
attachmentswhere any holds:- .content_type is 'application/pdf'
- .file_type is 'pdf'
any of:
any of:
- length(body.current_thread.text) < 500
- body.current_thread.text is missing
any of
map(...)where:- length(body.current_thread.text) - length(.) < 500
any of
attachmentswhere all hold:any of:
- .file_name matches 'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting'
any of
recipients.towhere all hold:- strings.icontains(.file_name)
- .email.domain.valid
- beta.parse_exif(.).title matches 'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting'
any of:
any of
file.explode(.)where:any of
[.scan.strings.raw, .scan.ocr.raw]where all hold:- . matches 'scan|camera|review and sign'
- . matches '\\bQR\\b|Q\\.R\\.|barcode'
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
- .scan.qr.url.domain.valid
any of
file.explode(.)where any holds:any of
[.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title]where:- . matches '\\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\\b'
all of:
any of
recipients.towhere:- strings.contains(.scan.ocr.raw)
all of:
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere all hold:- .name in ('Benefit Enrollment', 'Financial Communications')
- .confidence is not 'low'
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)
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_name, attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.local_part, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: beta.parse_exif, file.explode, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.contains, strings.icontains. Reference lists: $high_trust_sender_root_domains, $org_domains.
Indicators matched (11)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | application/pdf |
attachments[].file_type | equals | pdf |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | disclaimer |
regex.icontains | regex | salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting |
regex.icontains | regex | scan|camera|review and sign |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
file.explode(attachments[])[].scan.qr.type | equals | url |
regex.icontains | regex | \b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name | member | Benefit Enrollment |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name | member | Financial Communications |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence ne "low"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).topics)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence ne "low"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name in ["Benefit Enrollment", "Financial Communications"]
any(recipients.to)
strings.contains func_call "strings.contains(file.explode(attachments[])[].scan.ocr.raw)"
any([file.explode(attachments).scan.strings.raw, file.explode(attachments).scan.ocr.raw, file.explode(attachments).scan.exiftool.title])
[file.explode(attachments).scan.strings.raw, file.explode(attachments).scan.ocr.raw, file.explode(attachments).scan.exiftool.title] regex_match "\\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\\b"
or
any(file.explode(attachments))
any([file.explode(attachments).scan.strings.raw, file.explode(attachments).scan.ocr.raw])
and
[file.explode(attachments[])[].scan.strings.raw, file.explode(attachments[])[].scan.ocr.raw][] regex_match "\\bQR\\b|Q\\.R\\.|barcode"
[file.explode(attachments[])[].scan.strings.raw, file.explode(attachments[])[].scan.ocr.raw][] regex_match "scan|camera|review and sign"
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.qr.type eq "url"
file.explode(attachments[])[].scan.qr.url.domain.valid eq "true"
or
any(recipients.to)
and
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(attachments[].file_name)"
attachments.file_name regex_match "salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting"
beta.parse_exif(attachments[]).title regex_match "salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting"
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"
any(attachments)
or
attachments.content_type eq "application/pdf"
attachments.file_type eq "pdf"
or
any(map(...))
macro "(length(body.current_thread.text) - length(map(...)[])) < 500"
body.current_thread.text is_null
body.current_thread.text length_compare "500"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Compensation-themed DOCX with QR code credential theft
#Detects inbound messages containing DOCX attachments with compensation or benefit-related themes that include QR codes and suspicious indicators. The rule identifies files with reward/benefit language in filenames, compensation-related content in document metadata, and QR codes that may redirect to credential theft pages. It uses natural language processing to detect credential theft intent and suspicious topics like benefit enrollment or financial communications.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Social engineering, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
length(filter(attachments, .file_type == "docx")) >= 1
and (
// short or null message body
(
length(body.current_thread.text) < 500 or body.current_thread.text is null
)
// ignore disclaimers in body length calculation
or (
any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
.name == "disclaimer"
),
.text
),
(length(body.current_thread.text) - length(.)) < 500
)
)
)
)
and (
// attached DOCX contains a compensation review themed lure with a QR code and suspicious indicators
any(filter(attachments, .file_type == "docx"),
// add conditions for DOCX attachment
(
regex.icontains(.file_name,
'(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
)
// recipient email SLD in filename
or any(recipients.to,
strings.icontains(..file_name, .email.domain.sld)
and .email.domain.valid
)
or regex.icontains(beta.parse_exif(.).title,
'(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
)
)
// add conditions for text and any QR code within the DOCX attachment
and (
// conditions for QR code via text
any(file.explode(.),
any([.scan.strings.raw, .scan.ocr.raw],
regex.icontains(., 'scan|camera|review and sign')
and regex.icontains(., '\bQR\b|Q\.R\.|barcode')
)
or (
.scan.qr.type == "url"
and .scan.qr.url.url is not null
and any(recipients.to,
.email.domain.valid
and (
strings.icontains(..scan.qr.url.url, .email.email)
or any(strings.scan_base64(..scan.qr.url.url,
format="url"
),
strings.icontains(., ..email.email)
)
)
)
)
)
or any(file.explode(.),
.scan.qr.type == "url" and .scan.qr.url.domain.valid
)
)
// conditions for text
and any(file.explode(.),
// review/change terms in file content
any([.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title],
(
regex.icontains(.,
'\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b'
)
)
)
or (
// recipient local_part in attachment body
any(recipients.to,
strings.contains(..scan.ocr.raw, .email.local_part)
)
and (
// NLU cred_theft disposition
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence != "low"
)
// suspicious topics
and any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name in (
"Benefit Enrollment",
"Financial Communications"
)
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 containing DOCX attachments with compensation or benefit-related themes that include QR codes and suspicious indicators. The rule identifies files with reward/benefit language in filenames, compensation-related content in document metadata, and QR codes that may redirect to credential theft pages. It uses natural language processing to detect credential theft intent and suspicious topics like benefit enrollment or financial communications.
- inbound message
all of:
- length(filter(attachments, .file_type == 'docx')) ≥ 1
any of:
any of:
- length(body.current_thread.text) < 500
- body.current_thread.text is missing
any of
map(...)where:- length(body.current_thread.text) - length(.) < 500
any of
filter(attachments)where all hold:any of:
- .file_name matches '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
any of
recipients.towhere all hold:- strings.icontains(.file_name)
- .email.domain.valid
- beta.parse_exif(.).title matches '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
any of:
any of
file.explode(.)where any holds:any of
[.scan.strings.raw, .scan.ocr.raw]where all hold:- . matches 'scan|camera|review and sign'
- . matches '\\bQR\\b|Q\\.R\\.|barcode'
all of:
- .scan.qr.type is 'url'
- .scan.qr.url.url is set
any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.scan.qr.url.url)
any of
strings.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
- .scan.qr.url.domain.valid
any of
file.explode(.)where any holds:any of
[.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title]where:- . matches '\\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\\b'
all of:
any of
recipients.towhere:- strings.contains(.scan.ocr.raw)
all of:
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere all hold:- .name in ('Benefit Enrollment', 'Financial Communications')
- .confidence is not 'low'
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, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.email.domain.root_domain, type.inbound. Sensors: beta.parse_exif, file.explode, ml.nlu_classifier, regex.icontains, strings.contains, strings.icontains, strings.scan_base64. Reference lists: $high_trust_sender_root_domains.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | docx |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | disclaimer |
regex.icontains | regex | (?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?) |
regex.icontains | regex | scan|camera|review and sign |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
file.explode(filter(attachments)[])[].scan.qr.type | equals | url |
regex.icontains | regex | \b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b |
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].name | member | Benefit Enrollment |
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].name | member | Financial Communications |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
or
any(file.explode(filter(attachments)))
or
and
any(recipients.to)
and
or
any(strings.scan_base64(file.explode(filter(attachments)).scan.qr.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(filter(attachments)[])[].scan.qr.url.url)[])"
strings.icontains func_call "strings.icontains(file.explode(filter(attachments)[])[].scan.qr.url.url)"
recipients.to.email.domain.valid eq "true"
file.explode(filter(attachments)[])[].scan.qr.type eq "url"
file.explode(filter(attachments)[])[].scan.qr.url.url is_not_null
any([file.explode(filter(attachments)).scan.strings.raw, file.explode(filter(attachments)).scan.ocr.raw])
and
[file.explode(filter(attachments)[])[].scan.strings.raw, file.explode(filter(attachments)[])[].scan.ocr.raw][] regex_match "\\bQR\\b|Q\\.R\\.|barcode"
[file.explode(filter(attachments)[])[].scan.strings.raw, file.explode(filter(attachments)[])[].scan.ocr.raw][] regex_match "scan|camera|review and sign"
any(file.explode(filter(attachments)))
and
file.explode(filter(attachments)[])[].scan.qr.type eq "url"
file.explode(filter(attachments)[])[].scan.qr.url.domain.valid eq "true"
any(file.explode(filter(attachments)))
or
and
any(ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).intents)
and
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].confidence ne "low"
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].name eq "cred_theft"
any(ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).topics)
and
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].confidence ne "low"
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].name in ["Benefit Enrollment", "Financial Communications"]
any(recipients.to)
strings.contains func_call "strings.contains(file.explode(filter(attachments)[])[].scan.ocr.raw)"
any([file.explode(filter(attachments)).scan.strings.raw, file.explode(filter(attachments)).scan.ocr.raw, file.explode(filter(attachments)).scan.exiftool.title])
[file.explode(filter(attachments)).scan.strings.raw, file.explode(filter(attachments)).scan.ocr.raw, file.explode(filter(attachments)).scan.exiftool.title] regex_match "\\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\\b"
or
any(recipients.to)
and
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(filter(attachments)[].file_name)"
beta.parse_exif(filter(attachments)[]).title regex_match "(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)"
filter(attachments).file_name regex_match "(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
or
any(map(...))
macro "(length(body.current_thread.text) - length(map(...)[])) < 500"
body.current_thread.text is_null
body.current_thread.text length_compare "500"
filter(attachments, .file_type == 'docx') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Credit card application with WhatsApp contact
#Detects messages containing promotional credit card offers with attached forms requesting extensive personal information (PII) and directing victims to contact via WhatsApp, indicating potential fraud.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Social engineering, Out of band pivot |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// promotional/advertising content targeting financial services
and (
(
regex.icontains(body.current_thread.text,
"credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free|special offer"
)
or regex.icontains(subject.subject,
"credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free"
)
)
and any(ml.nlu_classifier(body.current_thread.text).topics,
.name in ("Advertising and Promotions")
)
)
// PII harvesting template in attachments (3+ of these patterns)
and any(attachments,
any(file.explode(.),
3 of (
regex.icontains(.scan.strings.raw, "Credit Card Application"),
regex.icontains(.scan.strings.raw, "Date of Birth"),
regex.icontains(.scan.strings.raw, "[eE]mail"),
regex.icontains(.scan.strings.raw, "[aA]ddress"),
regex.icontains(.scan.strings.raw, "Contact No"),
regex.icontains(.scan.strings.raw, "Pan No"),
regex.icontains(.scan.strings.raw, "ADHAAR"),
regex.icontains(.scan.strings.raw, "Annual.*salary"),
regex.icontains(.scan.strings.raw, "Mother Name"),
regex.icontains(.scan.strings.raw, "Father Name"),
regex.icontains(.scan.strings.raw, "SINGLE.*MARRIED")
)
)
)
// WhatsApp contact method (suspicious for legitimate financial institutions)
and (
regex.icontains(body.current_thread.text, "whatsapp")
or any(attachments,
any(file.explode(.), regex.icontains(.scan.qr.url.url, "wa\\.me"))
)
or any(file.explode(file.message_screenshot()),
regex.icontains(.scan.qr.url.url, "wa\\.me")
)
)
Detection logic
Scope: inbound message.
Detects messages containing promotional credit card offers with attached forms requesting extensive personal information (PII) and directing victims to contact via WhatsApp, indicating potential fraud.
- inbound message
all of:
any of:
- body.current_thread.text matches 'credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free|special offer'
- subject.subject matches 'credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free'
any of
ml.nlu_classifier(body.current_thread.text).topicswhere:- .name in ('Advertising and Promotions')
any of
attachmentswhere:any of
file.explode(.)where:at least 3 of 11: .scan.strings.raw matches any of 11 patterns
Credit Card ApplicationDate of Birth[eE]mail[aA]ddressContact NoPan NoADHAARAnnual.*salaryMother NameFather NameSINGLE.*MARRIED
any of:
- body.current_thread.text matches 'whatsapp'
any of
attachmentswhere:any of
file.explode(.)where:- .scan.qr.url.url matches 'wa\\\\.me'
any of
file.explode(...)where:- .scan.qr.url.url matches 'wa\\\\.me'
Inspects: body.current_thread.text, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, ml.nlu_classifier, regex.icontains.
Indicators matched (16)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free|special offer |
regex.icontains | regex | credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | Advertising and Promotions |
regex.icontains | regex | Credit Card Application |
regex.icontains | regex | Date of Birth |
regex.icontains | regex | [eE]mail |
regex.icontains | regex | [aA]ddress |
regex.icontains | regex | Contact No |
regex.icontains | regex | Pan No |
regex.icontains | regex | ADHAAR |
regex.icontains | regex | Annual.*salary |
regex.icontains | regex | Mother Name |
4 more
regex.icontains | regex | Father Name |
regex.icontains | regex | SINGLE.*MARRIED |
regex.icontains | regex | whatsapp |
regex.icontains | regex | wa\\.me |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
any(file.explode(attachments))
file.explode(attachments).scan.qr.url.url regex_match "wa\\\\.me"
any(file.explode(...))
file.explode(...).scan.qr.url.url regex_match "wa\\\\.me"
body.current_thread.text regex_match "whatsapp"
any(attachments)
any(file.explode(attachments))
or
file.explode(attachments[])[].scan.strings.raw regex_match "ADHAAR"
file.explode(attachments[])[].scan.strings.raw regex_match "Annual.*salary"
file.explode(attachments[])[].scan.strings.raw regex_match "Contact No"
file.explode(attachments[])[].scan.strings.raw regex_match "Credit Card Application"
file.explode(attachments[])[].scan.strings.raw regex_match "Date of Birth"
file.explode(attachments[])[].scan.strings.raw regex_match "Father Name"
file.explode(attachments[])[].scan.strings.raw regex_match "Mother Name"
file.explode(attachments[])[].scan.strings.raw regex_match "Pan No"
file.explode(attachments[])[].scan.strings.raw regex_match "SINGLE.*MARRIED"
file.explode(attachments[])[].scan.strings.raw regex_match "[aA]ddress"
file.explode(attachments[])[].scan.strings.raw regex_match "[eE]mail"
or
body.current_thread.text regex_match "credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free|special offer"
subject.subject regex_match "credit card.*offer|promotional.*credit|free.*credit card|lifetime.*free"
any(ml.nlu_classifier(body.current_thread.text).topics)
ml.nlu_classifier(body.current_thread.text).topics.name eq "Advertising and Promotions"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: CVE-2023-21716 - Microsoft Office Remote Code Execution Vulnerability
#Attachment contains an RTF file with a font table defining an excessive number of fonts, used to exploit CVE-2023-21716.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Exploit |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("rtf", "doc", "docx")
or .file_extension in~ $file_extensions_common_archives
or .file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
any(.scan.strings.strings, strings.ilike(., '*\fonttbl*'))
and length(filter(.scan.strings.strings,
strings.ilike(., '{\f*;}')
)
) > 10000
)
)
Detection logic
Scope: inbound message.
Attachment contains an RTF file with a font table defining an excessive number of fonts, used to exploit CVE-2023-21716.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('rtf', 'doc', 'docx')
- .file_extension in $file_extensions_common_archives
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . matches '*\\fonttbl*'
- length(filter(.scan.strings.strings, strings.ilike(., '{\\f*;}'))) > 10000
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | rtf |
attachments[].file_extension | member | doc |
attachments[].file_extension | member | docx |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *\fonttbl* |
strings.ilike | substring | {\f*;} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "\\fonttbl"
filter(file.explode(attachments[])[].scan.strings.strings, strings.ilike(file.explode(attachments[])[], '{\\f*;}')) length_compare "10000"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
attachments.file_extension in ["doc", "docx", "rtf"]
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Decoy PDF author (Julie P.)
#This detection rule matches on messages containing one or more Decoy PDF attachments with metadata discovered to have been assoicated with malicious email campaigns featuring CrowdStrike, DocuSign, Human Resource and password expiration lures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) > 0
and any(attachments,
.size <= 250000
and .file_extension == "pdf"
and any(file.explode(.),
(
.scan.exiftool.producer == "DocFly"
or any(.scan.exiftool.fields,
.key == "XMPToolkit"
and strings.icontains(.value, 'DynaPDF')
)
)
and (
any(.scan.exiftool.fields,
.key == "CreatorTool"
and .value == "Acrobat PDFMaker 24 for Word"
)
or any(.scan.exiftool.fields,
.key == "ContentTypeId"
and .value == "2.2388136001807807e+43"
)
or any(.scan.exiftool.fields,
.key == "Creator"
and .value in ('Julie Peters', 'Julie Pieters')
)
or any(.scan.exiftool.fields,
.key == "Author"
and .value in ('Julie Peters', 'Julie Pieters')
)
)
)
)
Detection logic
Scope: inbound message.
This detection rule matches on messages containing one or more Decoy PDF attachments with metadata discovered to have been assoicated with malicious email campaigns featuring CrowdStrike, DocuSign, Human Resource and password expiration lures.
- inbound message
- length(attachments) > 0
any of
attachmentswhere all hold:- .size ≤ 250000
- .file_extension is 'pdf'
any of
file.explode(.)where all hold:any of:
- .scan.exiftool.producer is 'DocFly'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'XMPToolkit'
- .value contains 'DynaPDF'
any of:
any of
.scan.exiftool.fieldswhere all hold:- .key is 'CreatorTool'
- .value is 'Acrobat PDFMaker 24 for Word'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'ContentTypeId'
- .value is '2.2388136001807807e+43'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'Creator'
- .value in ('Julie Peters', 'Julie Pieters')
any of
.scan.exiftool.fieldswhere all hold:- .key is 'Author'
- .value in ('Julie Peters', 'Julie Pieters')
Inspects: attachments[].file_extension, attachments[].size, type.inbound. Sensors: file.explode, strings.icontains.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
file.explode(attachments[])[].scan.exiftool.producer | equals | DocFly |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | XMPToolkit |
strings.icontains | substring | DynaPDF |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | CreatorTool |
file.explode(attachments[])[].scan.exiftool.fields[].value | equals | Acrobat PDFMaker 24 for Word |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | ContentTypeId |
file.explode(attachments[])[].scan.exiftool.fields[].value | equals | 2.2388136001807807e+43 |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | Creator |
file.explode(attachments[])[].scan.exiftool.fields[].value | member | Julie Peters |
file.explode(attachments[])[].scan.exiftool.fields[].value | member | Julie Pieters |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | Author |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Author"
file.explode(attachments[])[].scan.exiftool.fields[].value in ["Julie Peters", "Julie Pieters"]
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "ContentTypeId"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "2.2388136001807807e+43"
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Creator"
file.explode(attachments[])[].scan.exiftool.fields[].value in ["Julie Peters", "Julie Pieters"]
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "CreatorTool"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "Acrobat PDFMaker 24 for Word"
or
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "XMPToolkit"
file.explode(attachments[])[].scan.exiftool.fields[].value contains "DynaPDF"
file.explode(attachments[])[].scan.exiftool.producer eq "DocFly"
attachments.file_extension eq "pdf"
attachments.size le "250000"
attachments length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: DocuSign impersonation via PDF linking to new domain
#This rule detects PDF files containing a DocuSign logo linking to a newly created domain (Less than or equal to 3 days)
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
and any(ml.logo_detect(.).brands, .name == "DocuSign")
and any(file.explode(.),
any(.scan.pdf.urls, network.whois(.domain).days_old <= 3)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
// excludes senders that contain "via" in the display name a resilient way
and not (
any(headers.hops,
any(.fields,
.name == "X-Api-Host" and strings.ends_with(.value, "docusign.net")
)
)
)
Detection logic
Scope: inbound message.
This rule detects PDF files containing a DocuSign logo linking to a newly created domain (Less than or equal to 3 days)
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
ml.logo_detect(.).brandswhere:- .name is 'DocuSign'
any of
file.explode(.)where:any of
.scan.pdf.urlswhere:- network.whois(.domain).days_old ≤ 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
not:
any of
headers.hopswhere:any of
.fieldswhere all hold:- .name is 'X-Api-Host'
- .value ends with 'docusign.net'
Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, network.whois, strings.ends_with. Reference lists: $high_trust_sender_root_domains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
ml.logo_detect(attachments[]).brands[].name | equals | DocuSign |
Stages and Predicates
Stage 1: mql_rule
and
not
any(headers.hops)
any(headers.hops.fields)
and
headers.hops.fields[].name eq "X-Api-Host"
headers.hops.fields[].value ends_with "docusign.net"
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.pdf.urls)
network.whois func_call "network.whois(file.explode(attachments[])[].scan.pdf.urls[].domain).days_old <= 3"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name eq "DocuSign"
attachments.file_type eq "pdf"
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"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: DocX embedded binary
#This rule is designed to detect sophisticated phishing attacks that deliver binary payloads through MS office open XML files. It identifies malicious documents containing embedded scripts or objects, either encoded in base64 or using specific JavaScript functions like createObjectURL or msSaveOrOpenBlob, which are indicative of attempts to download and execute a binary payload.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or .content_type == "application/zip"
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
.file_extension in~ (
"doc",
"docm",
"docx",
"dot",
"dotm",
"xls",
"xlsx",
"xlsm",
"xlm",
"xlsb",
"xlt",
"xltm",
"ppt",
"pptx",
"pptm",
"ppsm"
)
and (
any(.flavors.yara, . == "base64_pe")
// The malicious file to be downloaded and run with the data URI may not always be portable executable
or any(.scan.strings.strings,
strings.ilike(., "*.createObjectURL(*)*")
)
or any(.scan.strings.strings,
strings.ilike(., "*.msSaveOrOpenBlob(*)*")
)
)
)
)
Detection logic
Scope: inbound message.
This rule is designed to detect sophisticated phishing attacks that deliver binary payloads through MS office open XML files. It identifies malicious documents containing embedded scripts or objects, either encoded in base64 or using specific JavaScript functions like createObjectURL or msSaveOrOpenBlob, which are indicative of attempts to download and execute a binary payload.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
- .content_type is 'application/zip'
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where all hold:- .file_extension in ('doc', 'docm', 'docx', 'dot', 'dotm', 'xls', 'xlsx', 'xlsm', 'xlm', 'xlsb', 'xlt', 'xltm', 'ppt', 'pptx', 'pptm', 'ppsm')
any of:
any of
.flavors.yarawhere:- . is 'base64_pe'
any of
.scan.strings.stringswhere:- . matches '*.createObjectURL(*)*'
any of
.scan.strings.stringswhere:- . matches '*.msSaveOrOpenBlob(*)*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (22)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | application/zip |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.explode(attachments[])[].file_extension | member | doc |
file.explode(attachments[])[].file_extension | member | docm |
file.explode(attachments[])[].file_extension | member | docx |
file.explode(attachments[])[].file_extension | member | dot |
file.explode(attachments[])[].file_extension | member | dotm |
file.explode(attachments[])[].file_extension | member | xls |
file.explode(attachments[])[].file_extension | member | xlsx |
file.explode(attachments[])[].file_extension | member | xlsm |
file.explode(attachments[])[].file_extension | member | xlm |
10 more
file.explode(attachments[])[].file_extension | member | xlsb |
file.explode(attachments[])[].file_extension | member | xlt |
file.explode(attachments[])[].file_extension | member | xltm |
file.explode(attachments[])[].file_extension | member | ppt |
file.explode(attachments[])[].file_extension | member | pptx |
file.explode(attachments[])[].file_extension | member | pptm |
file.explode(attachments[])[].file_extension | member | ppsm |
file.explode(attachments[])[].flavors.yara[] | equals | base64_pe |
strings.ilike | substring | *.createObjectURL(*)* |
strings.ilike | substring | *.msSaveOrOpenBlob(*)* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "base64_pe"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*.createObjectURL(*)*"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*.msSaveOrOpenBlob(*)*"
file.explode(attachments[])[].file_extension in ["doc", "docm", "docx", "dot", "dotm", "ppsm", "ppt", "pptm", "pptx", "xlm", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm"]
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
attachments.content_type eq "application/zip"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: DOCX with hyperlink targeting recipient address
#Detects DOCX attachments containing hyperlinks with anchor references that match recipient email addresses. This technique is commonly used to personalize malicious documents and evade detection.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_extension in ('docx', 'docm')),
any(filter(file.explode(.),
strings.icontains(.scan.strings.raw, '<w:hyperlink')
),
any(regex.iextract(.scan.strings.raw,
'<w:hyperlink[^\>]*w:anchor="(?P<email_address>[^\"]+)"'
),
.named_groups["email_address"] == recipients.to[0].email.email
or any(strings.scan_base64(.named_groups["email_address"],
ignore_padding=true
),
strings.icontains(., recipients.to[0].email.email)
)
)
)
)
Detection logic
Scope: inbound message.
Detects DOCX attachments containing hyperlinks with anchor references that match recipient email addresses. This technique is commonly used to personalize malicious documents and evade detection.
- inbound message
any of
filter(attachments)where:any of
filter(...)where:any of
regex.iextract(.scan.strings.raw)where any holds:- .named_groups['email_address'] is recipients.to[0].email.email
any of
strings.scan_base64(.named_groups['email_address'])where:- strings.icontains(.)
Inspects: attachments[].file_extension, recipients.to[0].email.email, type.inbound. Sensors: file.explode, regex.iextract, strings.icontains, strings.scan_base64.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | docx |
attachments[].file_extension | member | docm |
strings.icontains | substring | <w:hyperlink |
regex.iextract | regex | <w:hyperlink[^\>]*w:anchor="(?P<email_address>[^\"]+)" |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(filter(...))
any(regex.iextract(filter(...).scan.strings.raw))
or
any(strings.scan_base64(regex.iextract(filter(...).scan.strings.raw).named_groups['email_address']))
strings.icontains func_call "strings.icontains(strings.scan_base64(regex.iextract(filter(...)[].scan.strings.raw)[].named_groups['email_address'])[])"
regex.iextract(filter(...)[].scan.strings.raw)[].named_groups['email_address'] cross_field_compare "recipients.to[0].email.email"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: DOCX with malicious document template artifacts
#Detects inbound messages containing DOCX attachments with artifacts associated with malicious document templates.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Exploit |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "docx"),
any(file.explode(.),
any(.scan.yara.matches,
.name in ("malicious_docx_document_template_artifacts")
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing DOCX attachments with artifacts associated with malicious document templates.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('malicious_docx_document_template_artifacts')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | docx |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | malicious_docx_document_template_artifacts |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "malicious_docx_document_template_artifacts"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Double base64-encoded zip file in HTML smuggling attachment
#Qakbot double Base64 encodes zip files within their HTML smuggling email attachments. This leads to predictable file header strings appearing in the HTML string content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in ("html", "htm")
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(.,
// Double Base64 encoded zips
"*VUVzREJCUUFBUUFJQ*",
"*VFc0RCQlFBQVFBSU*",
"*VRXNEQkJRQUFRQUlB*",
// Reversed base64 strings double encoded zips
"*QJFUUBFUUCJERzVUV*",
"*USBFVQBFlQCR0cFV*",
"*BlUQRFUQRJkQENXRV*"
)
)
)
)
Detection logic
Scope: inbound message.
Qakbot double Base64 encodes zip files within their HTML smuggling email attachments. This leads to predictable file header strings appearing in the HTML string content.
- inbound message
any of
attachmentswhere all hold:- .file_extension in ('html', 'htm')
any of
file.explode(.)where:any of
.scan.strings.stringswhere:. matches any of 6 patterns
*VUVzREJCUUFBUUFJQ**VFc0RCQlFBQVFBSU**VRXNEQkJRQUFRQUlB**QJFUUBFUUCJERzVUV**USBFVQBFlQCR0cFV**BlUQRFUQRJkQENXRV*
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
strings.ilike | substring | *VUVzREJCUUFBUUFJQ* |
strings.ilike | substring | *VFc0RCQlFBQVFBSU* |
strings.ilike | substring | *VRXNEQkJRQUFRQUlB* |
strings.ilike | substring | *QJFUUBFUUCJERzVUV* |
strings.ilike | substring | *USBFVQBFlQCR0cFV* |
strings.ilike | substring | *BlUQRFUQRJkQENXRV* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "BlUQRFUQRJkQENXRV"
file.explode(attachments[])[].scan.strings.strings[] match "QJFUUBFUUCJERzVUV"
file.explode(attachments[])[].scan.strings.strings[] match "USBFVQBFlQCR0cFV"
file.explode(attachments[])[].scan.strings.strings[] match "VFc0RCQlFBQVFBSU"
file.explode(attachments[])[].scan.strings.strings[] match "VRXNEQkJRQUFRQUlB"
file.explode(attachments[])[].scan.strings.strings[] match "VUVzREJCUUFBUUFJQ"
attachments.file_extension in ["htm", "html"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Dropbox image lure with no Dropbox domains in links
#Detects Dropbox phishing emails with no Dropbox links with image attachments from an untrusted sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type not in $file_types_images)) == 0
and any(body.links,
not strings.ilike(.href_url.domain.root_domain, "dropbox.*")
)
and any(attachments,
.file_type in $file_types_images
and any(file.explode(.),
strings.ilike(.scan.ocr.raw, "*dropbox*")
and strings.ilike(.scan.ocr.raw, "*review*", "*sign*")
)
)
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.
Detects Dropbox phishing emails with no Dropbox links with image attachments from an untrusted sender.
- inbound message
- length(filter(attachments, .file_type not in $file_types_images)) is 0
any of
body.linkswhere:not:
- .href_url.domain.root_domain matches 'dropbox.*'
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of
file.explode(.)where all hold:- .scan.ocr.raw matches '*dropbox*'
.scan.ocr.raw matches any of 2 patterns
*review**sign*
any of:
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: file.explode, profile.by_sender, strings.ilike. Reference lists: $file_types_images.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.ilike | substring | *dropbox* |
strings.ilike | substring | *review* |
strings.ilike | substring | *sign* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
file.explode(attachments[])[].scan.ocr.raw match "review"
file.explode(attachments[])[].scan.ocr.raw match "sign"
file.explode(attachments[])[].scan.ocr.raw match "dropbox"
macro "attachments[].file_type in file_types_images"
any(body.links)
not
body.links.href_url.domain.root_domain starts_with "dropbox."
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"
filter(attachments, .file_type not in $file_types_images) length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Duplicated header pages in fraudulent multi-page PDF Request for Quotation
#Detects inbound PDF attachments between 2-3 pages where the first three lines of the header text appear nearly identical (within a Levenshtein distance of 5) on multiple pages, combined with terminology commonly found in fraudulent Request for Quotation (RFQ) documents such as procurement language, payment conditions, and preference point systems. This pattern is consistent with fabricated or manipulated procurement documents used in BEC or fraud schemes.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
//
// 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 1 < beta.parse_exif(.).page_count <= 3
//
// 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 beta.ocr(.).page_results[0].text != ""
// extract the first 3 lines from the first page
and any(regex.iextract(beta.ocr(.).page_results[0].text,
'^(?P<page_1_3_lines>(?:[^\r\n]+[\r\n]+){3})'
),
// make sure we have something
.named_groups["page_1_3_lines"] != ""
// either page 2 or page 3 contain VERY close text
// we have to do very close because sometimes the address format changes in trivial ways
// like a comma is removed or something
and (
any(regex.iextract(beta.ocr(..).page_results[1].text,
'^(?P<page_2_3_lines>(?:[^\r\n]+[\r\n]+){3})'
),
strings.levenshtein(.named_groups["page_2_3_lines"],
..named_groups["page_1_3_lines"]
) <= 5
)
or any(regex.iextract(beta.ocr(..).page_results[2].text,
'^(?P<page_3_3_lines>(?:[^\r\n]+[\r\n]+){3})'
),
strings.levenshtein(.named_groups["page_3_3_lines"],
..named_groups["page_1_3_lines"]
) <= 5
)
)
)
and (
3 of (
strings.icontains(beta.ocr(.).text,
"Contact Person",
"Date of issue",
"Date Issued",
"Closing Time and Date",
"Closing Date",
"QUOTATIONS ARE HEREBY INVITED FOR THE SUPPLY OF",
"COMPULSORY BIDDERS MUST QUOTE",
"Method of RFQ Submission"
),
strings.icontains(beta.ocr(.).text,
"Must be inclusive",
"Tax on Price Quotation",
"100% payment made in the form",
"Conditions for Release of Payment",
"Period of Validity of Quotes",
"Partial Bids",
"PRICING QUOTATION",
"Payment Terms and Conditions",
"freight, insurance until acceptance"
),
strings.icontains(beta.ocr(.).text,
"80/20 preference point system",
"80:20",
"Selection of suppliers will be based on",
"plant upgrade and maintenance",
"plant maintenance",
"without an Official Purchase Order",
"If unable to quote"
),
strings.icontains(beta.ocr(.).text,
"remain binding upon me/us",
"Authorized Signature",
"Name and Capacity",
"must be completed and accompanied by",
"This is not a Purchase Order"
)
)
)
)
Detection logic
Scope: inbound message.
Detects inbound PDF attachments between 2-3 pages where the first three lines of the header text appear nearly identical (within a Levenshtein distance of 5) on multiple pages, combined with terminology commonly found in fraudulent Request for Quotation (RFQ) documents such as procurement language, payment conditions, and preference point systems. This pattern is consistent with fabricated or manipulated procurement documents used in BEC or fraud schemes.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
all of:
- beta.parse_exif(.).page_count > 1
- beta.parse_exif(.).page_count ≤ 3
- beta.ocr(.).page_results[0].text is not ''
any of
regex.iextract(...)where all hold:- .named_groups['page_1_3_lines'] is not ''
any of:
any of
regex.iextract(...)where:- strings.levenshtein(.named_groups['page_2_3_lines']) ≤ 5
any of
regex.iextract(...)where:- strings.levenshtein(.named_groups['page_3_3_lines']) ≤ 5
at least 3 of 29: beta.ocr(.).text contains any of 29 patterns
Contact PersonDate of issueDate IssuedClosing Time and DateClosing DateQUOTATIONS ARE HEREBY INVITED FOR THE SUPPLY OFCOMPULSORY BIDDERS MUST QUOTEMethod of RFQ SubmissionMust be inclusiveTax on Price Quotation100% payment made in the formConditions for Release of PaymentPeriod of Validity of QuotesPartial BidsPRICING QUOTATIONPayment Terms and Conditionsfreight, insurance until acceptance80/20 preference point system80:20Selection of suppliers will be based onplant upgrade and maintenanceplant maintenancewithout an Official Purchase OrderIf unable to quoteremain binding upon me/usAuthorized SignatureName and Capacitymust be completed and accompanied byThis is not a Purchase Order
Inspects: attachments[].file_type, type.inbound. Sensors: beta.ocr, beta.parse_exif, regex.iextract, strings.icontains, strings.levenshtein.
Indicators matched (33)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.iextract | regex | ^(?P<page_1_3_lines>(?:[^\r\n]+[\r\n]+){3}) |
regex.iextract | regex | ^(?P<page_2_3_lines>(?:[^\r\n]+[\r\n]+){3}) |
regex.iextract | regex | ^(?P<page_3_3_lines>(?:[^\r\n]+[\r\n]+){3}) |
strings.icontains | substring | Contact Person |
strings.icontains | substring | Date of issue |
strings.icontains | substring | Date Issued |
strings.icontains | substring | Closing Time and Date |
strings.icontains | substring | Closing Date |
strings.icontains | substring | QUOTATIONS ARE HEREBY INVITED FOR THE SUPPLY OF |
strings.icontains | substring | COMPULSORY BIDDERS MUST QUOTE |
strings.icontains | substring | Method of RFQ Submission |
21 more
strings.icontains | substring | Must be inclusive |
strings.icontains | substring | Tax on Price Quotation |
strings.icontains | substring | 100% payment made in the form |
strings.icontains | substring | Conditions for Release of Payment |
strings.icontains | substring | Period of Validity of Quotes |
strings.icontains | substring | Partial Bids |
strings.icontains | substring | PRICING QUOTATION |
strings.icontains | substring | Payment Terms and Conditions |
strings.icontains | substring | freight, insurance until acceptance |
strings.icontains | substring | 80/20 preference point system |
strings.icontains | substring | 80:20 |
strings.icontains | substring | Selection of suppliers will be based on |
strings.icontains | substring | plant upgrade and maintenance |
strings.icontains | substring | plant maintenance |
strings.icontains | substring | without an Official Purchase Order |
strings.icontains | substring | If unable to quote |
strings.icontains | substring | remain binding upon me/us |
strings.icontains | substring | Authorized Signature |
strings.icontains | substring | Name and Capacity |
strings.icontains | substring | must be completed and accompanied by |
strings.icontains | substring | This is not a Purchase Order |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(regex.iextract(...))
and
or
any(regex.iextract(...))
strings.levenshtein func_call "strings.levenshtein(regex.iextract(...)[].named_groups['page_2_3_lines']) <= 5"
any(regex.iextract(...))
strings.levenshtein func_call "strings.levenshtein(regex.iextract(...)[].named_groups['page_3_3_lines']) <= 5"
regex.iextract(...).named_groups['page_1_3_lines'] ne ""
or
beta.ocr(attachments[]).text contains "100% payment made in the form"
beta.ocr(attachments[]).text contains "80/20 preference point system"
beta.ocr(attachments[]).text contains "80:20"
beta.ocr(attachments[]).text contains "Authorized Signature"
beta.ocr(attachments[]).text contains "COMPULSORY BIDDERS MUST QUOTE"
beta.ocr(attachments[]).text contains "Closing Date"
beta.ocr(attachments[]).text contains "Closing Time and Date"
beta.ocr(attachments[]).text contains "Conditions for Release of Payment"
beta.ocr(attachments[]).text contains "Contact Person"
beta.ocr(attachments[]).text contains "Date Issued"
beta.ocr(attachments[]).text contains "Date of issue"
beta.ocr(attachments[]).text contains "If unable to quote"
beta.ocr(attachments[]).text contains "Method of RFQ Submission"
beta.ocr(attachments[]).text contains "Must be inclusive"
beta.ocr(attachments[]).text contains "Name and Capacity"
beta.ocr(attachments[]).text contains "PRICING QUOTATION"
beta.ocr(attachments[]).text contains "Partial Bids"
beta.ocr(attachments[]).text contains "Payment Terms and Conditions"
beta.ocr(attachments[]).text contains "Period of Validity of Quotes"
beta.ocr(attachments[]).text contains "QUOTATIONS ARE HEREBY INVITED FOR THE SUPPLY OF"
beta.ocr(attachments[]).text contains "Selection of suppliers will be based on"
beta.ocr(attachments[]).text contains "Tax on Price Quotation"
beta.ocr(attachments[]).text contains "This is not a Purchase Order"
beta.ocr(attachments[]).text contains "freight, insurance until acceptance"
beta.ocr(attachments[]).text contains "must be completed and accompanied by"
beta.ocr(attachments[]).text contains "plant maintenance"
beta.ocr(attachments[]).text contains "plant upgrade and maintenance"
beta.ocr(attachments[]).text contains "remain binding upon me/us"
beta.ocr(attachments[]).text contains "without an Official Purchase Order"
attachments.file_type eq "pdf"
beta.ocr func_call "beta.ocr(attachments[]).page_results[0].text != "
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count <= 3"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count > 1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EICAR string present
#This rule detects the EICAR test string, used to evaluate Anti-Virus scanning and file inspection capabilities. For performance reasons, this rule is limited to attachments with "eicar" in the file name.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments, strings.icontains(.file_name, "eicar"))
and any(attachments,
any(file.explode(.),
any(.scan.strings.strings,
strings.icontains(.,
'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
)
)
)
)
Detection logic
Scope: inbound message.
This rule detects the EICAR test string, used to evaluate Anti-Virus scanning and file inspection capabilities. For performance reasons, this rule is limited to attachments with "eicar" in the file name.
- inbound message
any of
attachmentswhere:- .file_name contains 'eicar'
any of
attachmentswhere:any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . contains 'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
Inspects: attachments[].file_name, type.inbound. Sensors: file.explode, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | eicar |
strings.icontains | substring | X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"
any(attachments)
attachments.file_name contains "eicar"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Embedded Javascript in SVG file
#Javascript inside SVG files can be used to smuggle malicious payloads or execute scripts.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
(
.file_extension in~ ("svg", "svgz")
or .content_type in~ ("image/svg+xml")
or .file_type == "svg"
)
and (
strings.ilike(file.parse_text(.,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
).text,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
"*location.assign*",
"*decodeURIComponent*"
)
or regex.icontains(file.parse_text(.,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
).text,
'<iframe[^\>]+src\s*=\s*\"data:[^\;]+;base64,'
)
or any(beta.scan_base64(file.parse_text(.).text,
encodings=["ascii", "utf8", "utf16-le"]
),
strings.ilike(.,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
"*location.assign*",
"*decodeURIComponent*"
)
)
)
)
or (
(
.file_extension in $file_extensions_common_archives
or .file_type == "gz"
or .content_type == "application/x-gzip"
)
and any(file.explode(.),
(
.file_extension in~ ("svg", "svgz")
or .flavors.mime == "image/svg+xml"
)
and any(.scan.strings.strings,
strings.ilike(.,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
"*location.assign*",
"*decodeURIComponent*"
)
)
)
)
)
Detection logic
Scope: inbound message.
Javascript inside SVG files can be used to smuggle malicious payloads or execute scripts.
- inbound message
any of
attachmentswhere any holds:all of:
any of:
- .file_extension in ('svg', 'svgz')
- .content_type in ('image/svg+xml')
- .file_type is 'svg'
any of:
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*
- file.parse_text(., encodings=['ascii', 'utf8', 'utf16-le']).text matches '<iframe[^\\>]+src\\s*=\\s*\\"data:[^\\;]+;base64,'
any of
beta.scan_base64(...)where:. matches any of 9 patterns
*onload**window.location.href**onerror**CDATA**<script**</script**atob**location.assign**decodeURIComponent*
all of:
any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'gz'
- .content_type is 'application/x-gzip'
any of
file.explode(.)where all hold:any of:
- .file_extension in ('svg', 'svgz')
- .flavors.mime is 'image/svg+xml'
any of
.scan.strings.stringswhere:. matches any of 9 patterns
*onload**window.location.href**onerror**CDATA**<script**</script**atob**location.assign**decodeURIComponent*
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: beta.scan_base64, file.explode, file.parse_text, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (19)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | svg |
attachments[].file_extension | member | svgz |
attachments[].content_type | member | image/svg+xml |
attachments[].file_type | equals | svg |
strings.ilike | substring | *onload* |
strings.ilike | substring | *window.location.href* |
strings.ilike | substring | *onerror* |
strings.ilike | substring | *CDATA* |
strings.ilike | substring | *<script* |
strings.ilike | substring | *</script* |
strings.ilike | substring | *atob* |
strings.ilike | substring | *location.assign* |
7 more
strings.ilike | substring | *decodeURIComponent* |
regex.icontains | regex | <iframe[^\>]+src\s*=\s*\"data:[^\;]+;base64, |
attachments[].file_type | equals | gz |
attachments[].content_type | equals | application/x-gzip |
file.explode(attachments[])[].file_extension | member | svg |
file.explode(attachments[])[].file_extension | member | svgz |
file.explode(attachments[])[].flavors.mime | equals | image/svg+xml |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "</script"
file.explode(attachments[])[].scan.strings.strings[] match "<script"
file.explode(attachments[])[].scan.strings.strings[] match "CDATA"
file.explode(attachments[])[].scan.strings.strings[] match "atob"
file.explode(attachments[])[].scan.strings.strings[] match "decodeURIComponent"
file.explode(attachments[])[].scan.strings.strings[] match "location.assign"
file.explode(attachments[])[].scan.strings.strings[] match "onerror"
file.explode(attachments[])[].scan.strings.strings[] match "onload"
file.explode(attachments[])[].scan.strings.strings[] match "window.location.href"
or
file.explode(attachments[])[].file_extension in ["svg", "svgz"]
file.explode(attachments[])[].flavors.mime eq "image/svg+xml"
or
attachments.content_type eq "application/x-gzip"
attachments.file_type eq "gz"
macro "attachments[].file_extension in file_extensions_common_archives"
and
or
any(beta.scan_base64(...))
or
beta.scan_base64(...) match "</script"
beta.scan_base64(...) match "<script"
beta.scan_base64(...) match "CDATA"
beta.scan_base64(...) match "atob"
beta.scan_base64(...) match "decodeURIComponent"
beta.scan_base64(...) match "location.assign"
beta.scan_base64(...) match "onerror"
beta.scan_base64(...) match "onload"
beta.scan_base64(...) match "window.location.href"
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"
file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text regex_match "<iframe[^\\>]+src\\s*=\\s*\\\"data:[^\\;]+;base64,"
or
attachments.content_type eq "image/svg+xml"
attachments.file_extension in ["svg", "svgz"]
attachments.file_type eq "svg"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Embedded VBScript in MHT file
#MHT files can be used to run VBScript, which can run malicious code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension =~ "mht"
or .file_extension in~ $file_extensions_common_archives
)
// ensure there's an mht file (if it's in an archive)
and any(file.explode(.), .file_extension =~ "mht")
and any(file.explode(.),
any(.scan.html.scripts, .language == "VBScript")
)
)
Detection logic
Scope: inbound message.
MHT files can be used to run VBScript, which can run malicious code.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'mht'
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'mht'
any of
file.explode(.)where:any of
.scan.html.scriptswhere:- .language is 'VBScript'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | mht |
file.explode(attachments[])[].file_extension | equals | mht |
file.explode(attachments[])[].scan.html.scripts[].language | equals | VBScript |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.html.scripts)
file.explode(attachments).scan.html.scripts.language eq "VBScript"
or
attachments.file_extension eq "mht"
macro "attachments[].file_extension in file_extensions_common_archives"
any(file.explode(attachments))
file.explode(attachments).file_extension eq "mht"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML containing a base64 encoded script
#Attached EML contains a base64 encoded script in the message body.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(body.current_thread.text) < 1000
and any(attachments,
(.content_type == "message/rfc822" or .file_extension == "eml")
and strings.ilike(file.parse_eml(.).body.html.raw,
"*script*data:text/html;base64*"
)
)
// exclude bounce backs & read receipts
and not strings.like(sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
and not any(attachments, .content_type == "message/delivery-status")
Detection logic
Scope: inbound message.
Attached EML contains a base64 encoded script in the message body.
- inbound message
- length(body.current_thread.text) < 1000
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension is 'eml'
- file.parse_eml(.).body.html.raw matches '*script*data:text/html;base64*'
not:
sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
any of
attachmentswhere:- .content_type is 'message/delivery-status'
Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, sender.email.local_part, type.inbound. Sensors: file.parse_eml, strings.ilike, strings.like.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
strings.ilike | substring | *script*data:text/html;base64* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
file.parse_eml(attachments[]).body.html.raw wildcard "*script*data:text/html;base64*"
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"
body.current_thread.text length_compare "1000"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments | |
sender.email.local_part | match | administrator | excludes:sender.email.local_part field:"sender.email.local_part" value:"administrator" |
sender.email.local_part | match | mailer-daemon | excludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon" |
sender.email.local_part | match | postmaster | excludes:sender.email.local_part field:"sender.email.local_part" value:"postmaster" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML file contains HTML attachment with login portal indicators
#Attached EML file contains an HTML attachment with suspicious login indicators. Known credential theft technique.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// exclude bounce backs & read receipts
and not strings.like(sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
and not regex.imatch(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 (
(length(headers.references) == 0 and headers.in_reply_to is null)
or (
not strings.istarts_with(subject.subject, "re:")
and headers.in_reply_to is null
and not any(headers.hops, strings.ilike(.signature.headers, "*:reply-to"))
)
)
and any(attachments,
(.content_type == "message/rfc822" or .file_extension in ('eml'))
and any(file.explode(.),
// suspicious strings found in javascript
length(filter(.scan.javascript.strings,
strings.ilike(.,
"*username*",
"*login-form*",
"*email-form*",
"*Incorrect password. Please try again.*",
"*Password Incomplete, please try again*"
)
)
) >= 3
or (
// suspicious strings found outside of javascript, but binexplode'd file still of HTML type
.flavors.mime in~ ("text/html", "text/plain")
and 3 of (
any(.scan.strings.strings, strings.ilike(., "*username*")),
any(.scan.strings.strings, strings.ilike(., "*login-form*")),
any(.scan.strings.strings, strings.ilike(., "*email-form*")),
any(.scan.strings.strings,
strings.ilike(.,
"*Incorrect password. Please try again.*"
)
),
any(.scan.strings.strings,
strings.ilike(.,
"*Password Incomplete, please try again*"
)
)
)
)
or
// Known phishing obfuscation
2 of (
// Enter password
any(.scan.strings.strings,
strings.ilike(.,
"*&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*"
)
),
// Forgotten my password
any(.scan.strings.strings,
strings.ilike(.,
"*&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*"
)
),
// Sign in
any(.scan.strings.strings,
strings.ilike(.,
"*&#83;&#105;&#103;&#110;&#32;&#105;&#110*"
)
)
)
)
)
Detection logic
Scope: inbound message.
Attached EML file contains an HTML attachment with suspicious login indicators. Known credential theft technique.
- inbound message
not:
sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
- subject.subject matches '(undeliverable|read:).*'
not:
any of
attachmentswhere:- .content_type is 'message/delivery-status'
not:
any of
headers.referenceswhere:- strings.contains(body.html.display_text)
any of:
all of:
- length(headers.references) is 0
- headers.in_reply_to is missing
all of:
not:
- subject.subject starts with 're:'
- headers.in_reply_to is missing
not:
any of
headers.hopswhere:- .signature.headers matches '*:reply-to'
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension in ('eml')
any of
file.explode(.)where any holds:- length(filter(.scan.javascript.strings, strings.ilike(., '*username*', '*login-form*', '*email-form*', '*Incorrect password. Please try again.*', '*Password Incomplete, please try again*'))) ≥ 3
all of:
- .flavors.mime in ('text/html', 'text/plain')
at least 3 of:
any of
.scan.strings.stringswhere:- . matches '*username*'
any of
.scan.strings.stringswhere:- . matches '*login-form*'
any of
.scan.strings.stringswhere:- . matches '*email-form*'
any of
.scan.strings.stringswhere:- . matches '*Incorrect password. Please try again.*'
any of
.scan.strings.stringswhere:- . matches '*Password Incomplete, please try again*'
at least 2 of:
any of
.scan.strings.stringswhere:- . matches '*&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*'
any of
.scan.strings.stringswhere:- . matches '*&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*'
any of
.scan.strings.stringswhere:- . matches '*&#83;&#105;&#103;&#110;&#32;&#105;&#110*'
Inspects: attachments[].content_type, attachments[].file_extension, body.html.display_text, headers.hops, headers.hops[].signature.headers, headers.in_reply_to, headers.references, sender.email.local_part, subject.subject, type.inbound. Sensors: file.explode, regex.imatch, strings.contains, strings.ilike, strings.istarts_with, strings.like.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
strings.ilike | substring | *username* |
strings.ilike | substring | *login-form* |
strings.ilike | substring | *email-form* |
strings.ilike | substring | *Incorrect password. Please try again.* |
strings.ilike | substring | *Password Incomplete, please try again* |
file.explode(attachments[])[].flavors.mime | member | text/html |
file.explode(attachments[])[].flavors.mime | member | text/plain |
strings.ilike | substring | *&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100* |
strings.ilike | substring | *&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100* |
strings.ilike | substring | *&#83;&#105;&#103;&#110;&#32;&#105;&#110* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
or
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Incorrect password. Please try again."
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Password Incomplete, please try again"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "email-form"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "login-form"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "username"
file.explode(attachments[])[].flavors.mime in ["text/html", "text/plain"]
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#83;&#105;&#103;&#110;&#32;&#105;&#110"
filter(file.explode(attachments[])[].scan.javascript.strings, strings.ilike(file.explode(attachments[])[], '*username*', '*login-form*', '*email-form*', '*Incorrect password. Please try again.*', '*Password Incomplete, please try again*')) length_compare "3"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
or
and
not
any(headers.hops)
headers.hops.signature.headers ends_with ":reply-to"
not
subject.subject starts_with "re:"
headers.in_reply_to is_null
and
headers.in_reply_to is_null
headers.references length_compare "0"
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
subject.subject regex_match "(undeliverable|read:).*"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments | |
sender.email.local_part | match | administrator | excludes:sender.email.local_part field:"sender.email.local_part" value:"administrator" |
sender.email.local_part | match | mailer-daemon | excludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon" |
sender.email.local_part | match | postmaster | excludes:sender.email.local_part field:"sender.email.local_part" value:"postmaster" |
headers.references | array_any | excludes:headers.references | |
subject.subject | regex_match | (undeliverable|read:).* | excludes:subject.subject field:"subject.subject" value:"(undeliverable|read:).*" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML file with HTML attachment (unsolicited)
#Detects HTML files in EML attachments from unsolicited senders. Reduces attack surface against HTML smuggling.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// has EML attachment
and any(attachments,
(.file_extension == "eml" or .content_type == "message/rfc822")
and any(file.parse_eml(.).attachments,
// HTML file inside EML attachment
// we've seen files named ".htm.", which results in an empty
// .file_extension, so instead we look at .file_name
// they should be rare enough in EML attachments to not cause
// extraneous FPs
strings.ilike(.file_name, "*htm*")
or .file_type == "html"
or any(file.explode(.), .flavors.mime == "text/html")
)
)
// 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, .))
// unsolicited or fails authentation
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 (
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 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 HTML files in EML attachments from unsolicited senders. Reduces attack surface against HTML smuggling.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'eml'
- .content_type is 'message/rfc822'
any of
file.parse_eml(.).attachmentswhere any holds:- .file_name matches '*htm*'
- .file_type is 'html'
any of
file.explode(.)where:- .flavors.mime is 'text/html'
not:
sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
- subject.subject matches '^(undeliverable|read:)'
not:
any of
attachmentswhere:- .content_type is 'message/delivery-status'
not:
any of
headers.referenceswhere:- strings.contains(body.html.display_text)
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
all of:
- sender.email.domain.domain in $org_domains
not:
- coalesce(headers.auth_summary.dmarc.pass)
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: attachments[].content_type, attachments[].file_extension, body.html.display_text, headers.auth_summary.dmarc.pass, headers.references, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: file.explode, file.parse_eml, profile.by_sender_email, regex.icontains, strings.contains, strings.ilike, strings.like. Reference lists: $high_trust_sender_root_domains, $org_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | eml |
attachments[].content_type | equals | message/rfc822 |
strings.ilike | substring | *htm* |
file.parse_eml(attachments[]).attachments[].file_type | equals | html |
file.explode(file.parse_eml(attachments[]).attachments[])[].flavors.mime | equals | text/html |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.parse_eml(attachments).attachments)
or
any(file.explode(file.parse_eml(attachments).attachments))
file.explode(file.parse_eml(attachments).attachments).flavors.mime eq "text/html"
file.parse_eml(attachments[]).attachments[].file_name match "htm"
file.parse_eml(attachments[]).attachments[].file_type eq "html"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
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"
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)"
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(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
subject.subject regex_match "^(undeliverable|read:)"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments | |
sender.email.local_part | match | administrator | excludes:sender.email.local_part field:"sender.email.local_part" value:"administrator" |
sender.email.local_part | match | mailer-daemon | excludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon" |
sender.email.local_part | match | postmaster | excludes:sender.email.local_part field:"sender.email.local_part" value:"postmaster" |
headers.references | array_any | excludes:headers.references | |
subject.subject | regex_match | ^(undeliverable|read:) | excludes:subject.subject field:"subject.subject" value:"^(undeliverable|read:)" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML file with IPFS links
#Attached EML uses engaging language and IPFS links were detected in the EML file. IPFS has been recently observed hosting phishing sites.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Free file host, Free subdomain host, IPFS |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.content_type == "message/rfc822" or .file_extension in ('eml'))
and any(file.explode(.),
any(.scan.url.urls,
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.
Attached EML uses engaging language and IPFS links were detected in the EML file. IPFS has been recently observed hosting phishing sites.
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension in ('eml')
any of
file.explode(.)where:any of
.scan.url.urlswhere 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: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.explode, ml.link_analysis, regex.icontains, strings.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $tranco_1m, $umbrella_1m.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
strings.icontains | substring | ipfs |
regex.icontains | regex | [\.-/]ipfs|ipfs[\.-/] |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
or
and
or
and
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.domain not in tranco_1m"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.domain not in umbrella_1m"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.domain in free_file_hosts"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.root_domain in free_file_hosts"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.root_domain in free_subdomain_hosts"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.domain not in org_domains"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.path regex_match "[\\.-/]ipfs|ipfs[\\.-/]"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.url contains "ipfs"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML with embedded Javascript in SVG file
#Detects incoming messages containing EML attachments with embedded SVG files that contain malicious JavaScript code, including base64-encoded content and potentially harmful event handlers. The rule specifically watches for onload events, location redirects, error handlers, and iframe elements with base64 data URIs.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Scripting, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.content_type == "message/rfc822" or .file_extension =~ "eml")
and (
any(file.parse_eml(.).attachments,
.file_extension in~ ("svg", "svgz")
or .file_type == "svg"
and (
(
strings.ilike(file.parse_text(.,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
).text,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
'*location.assign*',
'*decodeURIComponent*'
)
or regex.icontains(file.parse_text(.,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
).text,
'<iframe[^\>]+src\s*=\s*\"data:[^\;]+;base64,'
)
or any(beta.scan_base64(file.parse_text(.).text,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
),
strings.ilike(.,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
'*location.assign*',
'*decodeURIComponent*'
)
)
)
or (
(
.file_extension in $file_extensions_common_archives
or .file_type == "gz"
or .content_type == "application/x-gzip"
)
and any(file.explode(.),
(
.file_extension in~ ("svg", "svgz")
or .flavors.mime == "image/svg+xml"
)
and any(.scan.strings.strings,
strings.ilike(.,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
"*location.assign*",
"*decodeURIComponent*"
)
)
)
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects incoming messages containing EML attachments with embedded SVG files that contain malicious JavaScript code, including base64-encoded content and potentially harmful event handlers. The rule specifically watches for onload events, location redirects, error handlers, and iframe elements with base64 data URIs.
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension is 'eml'
any of
file.parse_eml(.).attachmentswhere any holds:- .file_extension in ('svg', 'svgz')
all of:
- .file_type is 'svg'
any of:
any of:
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*
- file.parse_text(., encodings=['ascii', 'utf8', 'utf16-le']).text matches '<iframe[^\\>]+src\\s*=\\s*\\"data:[^\\;]+;base64,'
any of
beta.scan_base64(...)where:. matches any of 9 patterns
*onload**window.location.href**onerror**CDATA**<script**</script**atob**location.assign**decodeURIComponent*
all of:
any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'gz'
- .content_type is 'application/x-gzip'
any of
file.explode(.)where all hold:any of:
- .file_extension in ('svg', 'svgz')
- .flavors.mime is 'image/svg+xml'
any of
.scan.strings.stringswhere:. matches any of 9 patterns
*onload**window.location.href**onerror**CDATA**<script**</script**atob**location.assign**decodeURIComponent*
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: beta.scan_base64, file.explode, file.parse_eml, file.parse_text, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (20)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
file.parse_eml(attachments[]).attachments[].file_extension | member | svg |
file.parse_eml(attachments[]).attachments[].file_extension | member | svgz |
file.parse_eml(attachments[]).attachments[].file_type | equals | svg |
strings.ilike | substring | *onload* |
strings.ilike | substring | *window.location.href* |
strings.ilike | substring | *onerror* |
strings.ilike | substring | *CDATA* |
strings.ilike | substring | *<script* |
strings.ilike | substring | *</script* |
strings.ilike | substring | *atob* |
8 more
strings.ilike | substring | *location.assign* |
strings.ilike | substring | *decodeURIComponent* |
regex.icontains | regex | <iframe[^\>]+src\s*=\s*\"data:[^\;]+;base64, |
file.parse_eml(attachments[]).attachments[].file_type | equals | gz |
file.parse_eml(attachments[]).attachments[].content_type | equals | application/x-gzip |
file.explode(file.parse_eml(attachments[]).attachments[])[].file_extension | member | svg |
file.explode(file.parse_eml(attachments[]).attachments[])[].file_extension | member | svgz |
file.explode(file.parse_eml(attachments[]).attachments[])[].flavors.mime | equals | image/svg+xml |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.parse_eml(attachments).attachments)
or
and
or
and
any(file.explode(file.parse_eml(attachments).attachments))
and
any(file.explode(file.parse_eml(attachments).attachments).scan.strings.strings)
or
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "</script"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "<script"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "CDATA"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "atob"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "decodeURIComponent"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "location.assign"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "onerror"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "onload"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.strings.strings[] match "window.location.href"
or
file.explode(file.parse_eml(attachments[]).attachments[])[].file_extension in ["svg", "svgz"]
file.explode(file.parse_eml(attachments[]).attachments[])[].flavors.mime eq "image/svg+xml"
or
file.parse_eml(attachments[]).attachments[].content_type eq "application/x-gzip"
file.parse_eml(attachments[]).attachments[].file_type eq "gz"
macro "file.parse_eml(attachments[]).attachments[].file_extension in file_extensions_common_archives"
any(beta.scan_base64(...))
or
beta.scan_base64(...) match "</script"
beta.scan_base64(...) match "<script"
beta.scan_base64(...) match "CDATA"
beta.scan_base64(...) match "atob"
beta.scan_base64(...) match "decodeURIComponent"
beta.scan_base64(...) match "location.assign"
beta.scan_base64(...) match "onerror"
beta.scan_base64(...) match "onload"
beta.scan_base64(...) match "window.location.href"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "</script"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "<script"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "CDATA"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "atob"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "decodeURIComponent"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "location.assign"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "onerror"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "onload"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "window.location.href"
file.parse_text(file.parse_eml(attachments[]).attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text regex_match "<iframe[^\\>]+src\\s*=\\s*\\\"data:[^\\;]+;base64,"
file.parse_eml(attachments[]).attachments[].file_type eq "svg"
file.parse_eml(attachments[]).attachments[].file_extension in ["svg", "svgz"]
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML with Encrypted ZIP
#Detects when an EML file is attached that contains an encrypted ZIP file. The encryption can be used to bypass security scanning and deliver malicious content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// attached EML
and any(filter(attachments,
.content_type == "message/rfc822" or .file_extension in ('eml')
),
// Attached EML contains a ZIP file
any(filter(file.parse_eml(.).attachments,
.file_type == "zip" or .file_extension == "zip"
),
// ZIP file is encrypted
any(file.explode(.),
any(.flavors.yara, . == 'encrypted_zip') or .scan.zip.encrypted
)
)
)
Detection logic
Scope: inbound message.
Detects when an EML file is attached that contains an encrypted ZIP file. The encryption can be used to bypass security scanning and deliver malicious content.
- inbound message
any of
filter(attachments)where:any of
filter(...)where:any of
file.explode(.)where any holds:any of
.flavors.yarawhere:- . is 'encrypted_zip'
- .scan.zip.encrypted
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.explode, file.parse_eml.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
file.parse_eml(filter(attachments)[]).attachments[].file_type | equals | zip |
file.parse_eml(filter(attachments)[]).attachments[].file_extension | equals | zip |
file.explode(filter(...)[])[].flavors.yara[] | equals | encrypted_zip |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(filter(...))
any(file.explode(filter(...)))
or
any(file.explode(filter(...)).flavors.yara)
file.explode(filter(...)).flavors.yara eq "encrypted_zip"
file.explode(filter(...)[])[].scan.zip.encrypted eq "true"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML with link to credential phishing page
#Attached EML links to a credential phishing site or exhibits unusual behavior such as multiple suspicious redirects.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Free file host, Free subdomain host, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and any(attachments,
(.content_type == "message/rfc822" or .file_extension =~ "eml")
// identifies suspicious URLs in the attached EML
and any(file.parse_eml(.).body.links,
(
ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"
and ml.link_analysis(., mode="aggressive").credphish.confidence in (
"medium",
"high"
)
)
// or any links in the final dom lead to a suspicious tld
or any(ml.link_analysis(.).final_dom.links,
.href_url.domain.tld in $suspicious_tlds
or ml.link_analysis(.href_url).effective_url.domain.tld in $suspicious_tlds
)
// link redirects to a suspicious TLD
or any(ml.link_analysis(., mode="aggressive").redirect_history,
.domain.tld in $suspicious_tlds
)
or (
// 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
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
)
)
// identifies other suspicious indicators
and (
// engaging language in the original body
any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request"
)
// // engaging language in the attached EML
or any(ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).entities,
.name == "request"
)
// recipient SLD impersonated in the subject or display name
or any(recipients.to,
// ensure that we're checking the org SLD
.email.domain.sld in $org_slds
and (
strings.icontains(subject.subject, .email.domain.sld)
or strings.icontains(sender.display_name, .email.domain.sld)
)
)
// mismatched sender (From) and Reply-to + freemail
or (
length(headers.reply_to) > 0
and all(headers.reply_to,
.email.domain.root_domain != sender.email.domain.root_domain
and .email.domain.root_domain in $free_email_providers
)
)
or any($suspicious_subjects, strings.icontains(subject.subject, .))
or 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",
"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",
)
)
)
// exclude bounce backs & read receipts
and not strings.ilike(sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
// exclude optonline deprecated mailbox returns
and (
not strings.starts_with(sender.display_name, "Auto-reply")
and sender.email.domain.root_domain == "optonline.net"
)
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().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.
Attached EML links to a credential phishing site or exhibits unusual behavior such as multiple suspicious redirects.
- inbound message
- length(attachments) is 1
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension is 'eml'
any of
file.parse_eml(.).body.linkswhere any holds:all of:
- ml.link_analysis(.).credphish.disposition is 'phishing'
- ml.link_analysis(.).credphish.confidence in ('medium', 'high')
any of
ml.link_analysis(.).final_dom.linkswhere any holds:- .href_url.domain.tld in $suspicious_tlds
- ml.link_analysis(.href_url).effective_url.domain.tld in $suspicious_tlds
any of
ml.link_analysis(., mode='aggressive').redirect_historywhere:- .domain.tld in $suspicious_tlds
all of:
- 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
any of:
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name is 'request'
any of
ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).entitieswhere:- .name is 'request'
any of
recipients.towhere all hold:- .email.domain.sld in $org_slds
any of:
- strings.icontains(subject.subject)
- strings.icontains(sender.display_name)
all of:
- length(headers.reply_to) > 0
all of
headers.reply_towhere all hold:- .email.domain.root_domain is not sender.email.domain.root_domain
- .email.domain.root_domain in $free_email_providers
any of
$suspicious_subjectswhere:- strings.icontains(subject.subject)
subject.subject matches any of 123 patterns
termination.*notice38417: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 .*disablaction.*requiredabandon.*packageabout.your.accountacc(ou)?n?t (is )?on ho[li]dacc(ou)?n?t.*terminatacc(oun)?t.*[il1]{2}mitationaccess.*limitationaccount (will be )?blockaccount.*de-?activataccount.*lockedaccount.*re-verificationaccount.*securityaccount.*suspensionaccount.has.beenaccount.has.expiredaccount.will.be.blockedaccount v[il]o[li]atactivity.*acc(oun)?talmost.fullapp[li]e.[il]dauthenticate.*accountbeen.*suspendclos.*of.*account.*processedconfirm.your.accountcourier.*ablecrediential.*notifdeactivation.*in.*progressdelivery.*attempt.*faileddocument.receiveddocumented.*shared.*with.*youdropbox.*documente-?ma[il1]+ .{010}suspene-?ma[il1]{1} usere-?ma[il1]{2} acce-?ma[il1]{2}.*up.?gradee.?ma[il1]{2}.*servere.?ma[il1]{2}.*suspendemail.updatefaxed youfraud(ulent)?.*chargefrom.helpdeskfu[il1]{2}.*ma[il1]+[ -]?boxhas.been.*suspendedhas.been.limitedhave.lockedhe[li]p ?desk upgradeheipdeski[il]iega[il]ii[il]ega[il]incoming e?mailincoming.*faxlock.*securityma[il1]{1}[ -]?box.*quoma[il1]{2}[ -]?box.*fu[il1]ma[il1]{2}box.*[il1]{2}mitma[il1]{2}box stormail on.?holdmail.*box.*migrationmail.*de-?activatmail.update.requiredmails.*pendingmessages.*pendingmissed.*shipping.*notificationmissed.shipment.notificationmust.update.your.accountnew [sl][io]g?[nig][ -]?in fromnew voice ?-?mailnotifications.*pendingoffice.*3.*6.*5.*suspendoffice365on google docs with youonline docpassword.*compromisedperiodic maintenancepotential(ly)? unauthorizedrefund not approvedreportrevised.*policyscamscanned.?invoicesecured?.updatesecurity breachsecurltysigned.*deliverystatus of your .{314}? ?deliverysusp[il1]+c[il1]+ous.*act[il1]+v[il1]+tysuspicious.*sign.*[io]nsuspicious.activittemporar(il)?y deactivatetemporar[il1]{2}y disab[li]edtemporarily.*lockun-?usua[li].activityunable.*deliverunauthorized.*activitunauthorized.deviceundelivered messageunread.*docunusual.activityupgrade.*accountupgrade.noticeurgent messageurgent.verificationv[il1]o[li1]at[il1]on securityva[il1]{1}date.*ma[il1]{2}[ -]?boxverification ?-?requireverification( )?-?needverify.your?.accountweb ?-?ma[il1]{2}web[ -]?ma[il1]{2}will.be.suspendedyour (customer )?account .asyour.office.365your.online.access
not:
sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
all of:
not:
- sender.display_name starts with 'Auto-reply'
- sender.email.domain.root_domain is 'optonline.net'
not:
- subject.subject matches '^(undeliverable|read:)'
not:
any of
attachmentswhere:- .content_type is 'message/delivery-status'
not:
any of
headers.referenceswhere:- strings.contains(body.html.display_text)
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, body.html.display_text, headers.references, headers.reply_to, headers.reply_to[].email.domain.root_domain, recipients.to, recipients.to[].email.domain.sld, sender.display_name, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: file.parse_eml, ml.link_analysis, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.contains, strings.icontains, strings.ilike, strings.starts_with. Reference lists: $free_email_providers, $org_slds, $suspicious_subjects, $suspicious_tlds.
Indicators matched (128)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).entities[].name | equals | request |
regex.icontains | regex | termination.*notice |
regex.icontains | regex | 38417 |
regex.icontains | regex | :completed |
regex.icontains | regex | [il1]{2}mit.*ma[il1]{2} ?bo?x |
regex.icontains | regex | [il][il][il]egai[ -] |
regex.icontains | regex | [li][li][li]ega[li] attempt |
regex.icontains | regex | [ng]-?[io]n .*block |
regex.icontains | regex | [ng]-?[io]n .*cancel |
116 more
regex.icontains | regex | [ng]-?[io]n .*deactiv |
regex.icontains | regex | [ng]-?[io]n .*disabl |
regex.icontains | regex | action.*required |
regex.icontains | regex | abandon.*package |
regex.icontains | regex | about.your.account |
regex.icontains | regex | acc(ou)?n?t (is )?on ho[li]d |
regex.icontains | regex | acc(ou)?n?t.*terminat |
regex.icontains | regex | acc(oun)?t.*[il1]{2}mitation |
regex.icontains | regex | access.*limitation |
regex.icontains | regex | account (will be )?block |
regex.icontains | regex | account.*de-?activat |
regex.icontains | regex | account.*locked |
regex.icontains | regex | account.*re-verification |
regex.icontains | regex | account.*security |
regex.icontains | regex | account.*suspension |
regex.icontains | regex | account.has.been |
regex.icontains | regex | account.has.expired |
regex.icontains | regex | account.will.be.blocked |
regex.icontains | regex | account v[il]o[li]at |
regex.icontains | regex | activity.*acc(oun)?t |
regex.icontains | regex | almost.full |
regex.icontains | regex | app[li]e.[il]d |
regex.icontains | regex | authenticate.*account |
regex.icontains | regex | been.*suspend |
regex.icontains | regex | clos.*of.*account.*processed |
regex.icontains | regex | confirm.your.account |
regex.icontains | regex | courier.*able |
regex.icontains | regex | crediential.*notif |
regex.icontains | regex | deactivation.*in.*progress |
regex.icontains | regex | delivery.*attempt.*failed |
regex.icontains | regex | document.received |
regex.icontains | regex | documented.*shared.*with.*you |
regex.icontains | regex | dropbox.*document |
regex.icontains | regex | e-?ma[il1]+ .{010}suspen |
regex.icontains | regex | e-?ma[il1]{1} user |
regex.icontains | regex | e-?ma[il1]{2} acc |
regex.icontains | regex | e-?ma[il1]{2}.*up.?grade |
regex.icontains | regex | e.?ma[il1]{2}.*server |
regex.icontains | regex | e.?ma[il1]{2}.*suspend |
regex.icontains | regex | email.update |
regex.icontains | regex | faxed you |
regex.icontains | regex | fraud(ulent)?.*charge |
regex.icontains | regex | from.helpdesk |
regex.icontains | regex | fu[il1]{2}.*ma[il1]+[ -]?box |
regex.icontains | regex | has.been.*suspended |
regex.icontains | regex | has.been.limited |
regex.icontains | regex | have.locked |
regex.icontains | regex | he[li]p ?desk upgrade |
regex.icontains | regex | heipdesk |
regex.icontains | regex | i[il]iega[il] |
regex.icontains | regex | ii[il]ega[il] |
regex.icontains | regex | incoming e?mail |
regex.icontains | regex | incoming.*fax |
regex.icontains | regex | lock.*security |
regex.icontains | regex | ma[il1]{1}[ -]?box.*quo |
regex.icontains | regex | ma[il1]{2}[ -]?box.*fu[il1] |
regex.icontains | regex | ma[il1]{2}box.*[il1]{2}mit |
regex.icontains | regex | ma[il1]{2}box stor |
regex.icontains | regex | mail on.?hold |
regex.icontains | regex | mail.*box.*migration |
regex.icontains | regex | mail.*de-?activat |
regex.icontains | regex | mail.update.required |
regex.icontains | regex | mails.*pending |
regex.icontains | regex | messages.*pending |
regex.icontains | regex | missed.*shipping.*notification |
regex.icontains | regex | missed.shipment.notification |
regex.icontains | regex | must.update.your.account |
regex.icontains | regex | new [sl][io]g?[nig][ -]?in from |
regex.icontains | regex | new voice ?-?mail |
regex.icontains | regex | notifications.*pending |
regex.icontains | regex | office.*3.*6.*5.*suspend |
regex.icontains | regex | office365 |
regex.icontains | regex | on google docs with you |
regex.icontains | regex | online doc |
regex.icontains | regex | password.*compromised |
regex.icontains | regex | periodic maintenance |
regex.icontains | regex | potential(ly)? unauthorized |
regex.icontains | regex | refund not approved |
regex.icontains | regex | report |
regex.icontains | regex | revised.*policy |
regex.icontains | regex | scam |
regex.icontains | regex | scanned.?invoice |
regex.icontains | regex | secured?.update |
regex.icontains | regex | security breach |
regex.icontains | regex | securlty |
regex.icontains | regex | signed.*delivery |
regex.icontains | regex | status of your .{314}? ?delivery |
regex.icontains | regex | susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty |
regex.icontains | regex | suspicious.*sign.*[io]n |
regex.icontains | regex | suspicious.activit |
regex.icontains | regex | temporar(il)?y deactivate |
regex.icontains | regex | temporar[il1]{2}y disab[li]ed |
regex.icontains | regex | temporarily.*lock |
regex.icontains | regex | un-?usua[li].activity |
regex.icontains | regex | unable.*deliver |
regex.icontains | regex | unauthorized.*activit |
regex.icontains | regex | unauthorized.device |
regex.icontains | regex | undelivered message |
regex.icontains | regex | unread.*doc |
regex.icontains | regex | unusual.activity |
regex.icontains | regex | upgrade.*account |
regex.icontains | regex | upgrade.notice |
regex.icontains | regex | urgent message |
regex.icontains | regex | urgent.verification |
regex.icontains | regex | v[il1]o[li1]at[il1]on security |
regex.icontains | regex | va[il1]{1}date.*ma[il1]{2}[ -]?box |
regex.icontains | regex | verification ?-?require |
regex.icontains | regex | verification( )?-?need |
regex.icontains | regex | verify.your?.account |
regex.icontains | regex | web ?-?ma[il1]{2} |
regex.icontains | regex | web[ -]?ma[il1]{2} |
regex.icontains | regex | will.be.suspended |
regex.icontains | regex | your (customer )?account .as |
regex.icontains | regex | your.office.365 |
regex.icontains | regex | your.online.access |
sender.email.domain.root_domain | equals | optonline.net |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.parse_eml(attachments).body.links)
or
any(ml.link_analysis(file.parse_eml(attachments).body.links).final_dom.links)
or
ml.link_analysis func_call "ml.link_analysis(ml.link_analysis(file.parse_eml(attachments[]).body.links[]).final_dom.links[].href_url).effective_url.domain.tld in suspicious_tlds"
macro "ml.link_analysis(file.parse_eml(attachments[]).body.links[]).final_dom.links[].href_url.domain.tld in suspicious_tlds"
and
distinct(map(ml.link_analysis(file.parse_eml(attachments[]).body.links[], mode='aggressive').redirect_history, file.parse_eml(attachments[]).body.links[].domain.domain)) length_compare "3"
distinct(map(ml.link_analysis(file.parse_eml(attachments[]).body.links[], mode='aggressive').redirect_history, file.parse_eml(attachments[]).body.links[].domain.tld)) length_compare "2"
and
ml.link_analysis func_call "ml.link_analysis(file.parse_eml(attachments[]).body.links[]).credphish.confidence in (medium, high)"
ml.link_analysis func_call "ml.link_analysis(file.parse_eml(attachments[]).body.links[]).credphish.disposition == phishing"
any(ml.link_analysis(file.parse_eml(attachments).body.links, mode='aggressive').redirect_history)
macro "ml.link_analysis(file.parse_eml(attachments[]).body.links[], mode='aggressive').redirect_history[].domain.tld in suspicious_tlds"
or
any(recipients.to)
and
or
strings.icontains func_call "strings.icontains(sender.display_name)"
strings.icontains func_call "strings.icontains(subject.subject)"
macro "recipients.to[].email.domain.sld in org_slds"
and
headers.reply_to length_compare "0"
macro "all(headers.reply_to)"
any(ml.nlu_classifier(body.current_thread.text).entities)
ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
any(ml.nlu_classifier(file.parse_eml(attachments).body.current_thread.text).entities)
ml.nlu_classifier(file.parse_eml(attachments).body.current_thread.text).entities.name eq "request"
any($suspicious_subjects)
strings.icontains func_call "strings.icontains(subject.subject)"
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 "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
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
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(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
sender.display_name starts_with "Auto-reply"
not
subject.subject regex_match "^(undeliverable|read:)"
attachments length_compare "1"
sender.email.domain.root_domain eq "optonline.net"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments | |
sender.email.local_part | match | administrator | excludes:sender.email.local_part field:"sender.email.local_part" value:"administrator" |
sender.email.local_part | match | mailer-daemon | excludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon" |
sender.email.local_part | match | postmaster | excludes:sender.email.local_part field:"sender.email.local_part" value:"postmaster" |
headers.references | array_any | excludes:headers.references | |
sender.display_name | starts_with | Auto-reply | excludes:sender.display_name field:"sender.display_name" value:"Auto-reply" |
subject.subject | regex_match | ^(undeliverable|read:) | excludes:subject.subject field:"subject.subject" value:"^(undeliverable|read:)" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.email.domain.root_domain | eq |
| field:"sender.email.domain.root_domain" kind:eq value:"optonline.net" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML with QR code redirecting to Cloudflare challenges
#Detects EML attachments containing office documents, PDFs, or images with embedded QR codes that redirect to Cloudflare challenge pages, potentially used to bypass security measures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(attachments,
// Email Attachments
any(file.parse_eml(.).attachments,
(
// looks for office docs in the attached eml
.file_extension in $file_extensions_macros
and any(file.explode(.),
.scan.qr.type == "url"
and regex.icontains(ml.link_analysis(.scan.qr.url).final_dom.raw,
'challenges\.cloudflare\.com',
)
)
)
or (
// looks for pdfs and images in the attached eml
//
// 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(beta.scan_qr(.).items,
.type is not null
and regex.icontains(ml.link_analysis(.url).final_dom.raw,
'challenges\.cloudflare\.com'
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects EML attachments containing office documents, PDFs, or images with embedded QR codes that redirect to Cloudflare challenge pages, potentially used to bypass security measures.
- inbound message
- length(recipients.to) is 1
- recipients.to[0].email.domain.valid
any of
attachmentswhere:any of
file.parse_eml(.).attachmentswhere any holds:all of:
- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
- ml.link_analysis(.scan.qr.url).final_dom.raw matches 'challenges\\.cloudflare\\.com'
any of
beta.scan_qr(.).itemswhere all hold:- .type is set
- ml.link_analysis(.url).final_dom.raw matches 'challenges\\.cloudflare\\.com'
Inspects: recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: beta.scan_qr, file.explode, file.parse_eml, ml.link_analysis, regex.icontains. Reference lists: $file_extensions_macros.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.type | equals | url |
regex.icontains | regex | challenges\.cloudflare\.com |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.parse_eml(attachments).attachments)
or
and
any(file.explode(file.parse_eml(attachments).attachments))
and
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.type eq "url"
ml.link_analysis(file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url).final_dom.raw regex_match "challenges\\.cloudflare\\.com"
macro "file.parse_eml(attachments[]).attachments[].file_extension in file_extensions_macros"
any(beta.scan_qr(file.parse_eml(attachments).attachments).items)
and
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].type is_not_null
ml.link_analysis(beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url).final_dom.raw regex_match "challenges\\.cloudflare\\.com"
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.
Attachment: EML with suspicious indicators
#Attached EML contains suspicious indicators, such as a missing sender email or short HTML body.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
// a single attachmed EML
length(attachments) == 1
// or a single attached EML with one or more images used in the body of the message
// likely within the signatures
or (
length(filter(attachments,
.file_extension == "eml" or .content_type == "message/rfc822"
)
) == 1
and length(filter(attachments,
.file_type in $file_types_images
and (
any(regex.extract(.content_id, '^<(?P<cid>.*)\>$'),
strings.icontains(body.html.raw,
.named_groups["cid"]
)
)
or strings.icontains(body.html.raw, .content_id)
)
)
) == length(attachments) - 1
)
)
and (
length(body.current_thread.text) < 300
or body.current_thread.text is null
or any(ml.nlu_classifier(body.current_thread.text).intents,
.name in ("cred_theft", "steal_pii")
)
)
and not any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "benign" and .confidence == "high"
)
and any(attachments,
(.file_extension == "eml" or .content_type == "message/rfc822")
and (
// suspicious indicators
file.parse_eml(.).sender.email.email == ""
or length(file.parse_eml(.).body.html.raw) < 10
or length(file.parse_eml(.).headers.hops) < 2
// the sender of the outer message is the recipient of the outer message
// and the sender and recipient of the inner message
or (
sender.email.email in map(recipients.to, .email.email)
and length(recipients.to) == 1
and sender.email.email == file.parse_eml(.).sender.email.email
and sender.email.email in map(file.parse_eml(.).recipients.to,
.email.email
)
and length(file.parse_eml(.).recipients.to) == 1
)
)
and not (
all(file.parse_eml(.).body.links,
.href_url.domain.root_domain in ("aka.ms", "office365.com")
or .href_url.url == "#additionalatt"
)
and strings.icontains(file.parse_eml(.).body.current_thread.text,
"We’re making sure your attachments are safe"
)
)
and file.parse_eml(.).sender.email.domain.root_domain not in $org_domains
)
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.
Attached EML contains suspicious indicators, such as a missing sender email or short HTML body.
- inbound message
any of:
- length(attachments) is 1
all of:
- length(filter(attachments, .file_extension == 'eml' or .content_type == 'message/rfc822')) is 1
- length(filter(attachments, .file_type in $file_types_images and any(regex.extract(.content_id, '^<(?P<cid>.*)\\>$'), strings.icontains(body.html.raw, .named_groups['cid'])) or strings.icontains(body.html.raw, .content_id))) is length(attachments) - 1
any of:
- length(body.current_thread.text) < 300
- body.current_thread.text is missing
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name in ('cred_theft', 'steal_pii')
not:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'benign'
- .confidence is 'high'
any of
attachmentswhere all hold:any of:
- .file_extension is 'eml'
- .content_type is 'message/rfc822'
any of:
- file.parse_eml(.).sender.email.email is ''
- length(file.parse_eml(.).body.html.raw) < 10
- length(file.parse_eml(.).headers.hops) < 2
all of:
- sender.email.email in map(recipients.to, .email.email)
- length(recipients.to) is 1
- sender.email.email is file.parse_eml(.).sender.email.email
- sender.email.email in map(file.parse_eml(.).recipients.to, .email.email)
- length(file.parse_eml(.).recipients.to) is 1
not:
all of:
all of
file.parse_eml(.).body.linkswhere any holds:- .href_url.domain.root_domain in ('aka.ms', 'office365.com')
- .href_url.url is '#additionalatt'
- file.parse_eml(.).body.current_thread.text contains 'We’re making sure your attachments are safe'
- file.parse_eml(.).sender.email.domain.root_domain not in $org_domains
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
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_id, attachments[].content_type, attachments[].file_extension, attachments[].file_type, body.current_thread.text, body.html.raw, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.parse_eml, ml.nlu_classifier, profile.by_sender, regex.extract, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | eml |
attachments[].content_type | equals | message/rfc822 |
regex.extract | regex | ^<(?P<cid>.*)\>$ |
ml.nlu_classifier(body.current_thread.text).intents[].name | member | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].name | member | steal_pii |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
not
and
file.parse_eml(attachments[]).body.current_thread.text contains "We’re making sure your attachments are safe"
macro "all(file.parse_eml(attachments[]).body.links)"
or
and
file.parse_eml(attachments[]).recipients.to length_compare "1"
recipients.to length_compare "1"
macro "sender.email.email == file.parse_eml(attachments[]).sender.email.email"
macro "sender.email.email in map(file.parse_eml(attachments[]).recipients.to, attachments[].email.email)"
macro "sender.email.email in map(recipients.to, attachments[].email.email)"
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.email == "
file.parse_eml(attachments[]).body.html.raw length_compare "10"
file.parse_eml(attachments[]).headers.hops length_compare "2"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.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"
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"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
and
filter(attachments, .file_extension == 'eml' or .content_type == 'message/rfc822') length_compare "1"
macro "length(filter(attachments, .file_type in $file_types_images and any(regex.extract(.content_id, '^<(?P<cid>.*)\\\\>$'), strings.icontains(body.html.raw, .named_groups['cid'])) or strings.icontains(body.html.raw, .content_id))) == (length(attachments) - 1)"
attachments length_compare "1"
or
any(ml.nlu_classifier(body.current_thread.text).intents)
ml.nlu_classifier(body.current_thread.text).intents.name in ["cred_theft", "steal_pii"]
body.current_thread.text is_null
body.current_thread.text length_compare "300"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents | array_any | excludes:ml.nlu_classifier(body.current_thread.text).intents |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Emotet heavily padded doc in zip file
#Detects a potential Emotet delivery method using padded .doc files that compress into small zip files. Contents may include Red Dawn templates exceeding 500MB.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension == "zip"
and any(file.explode(.),
.depth == 0
and .size < 1000000
and not .depth > 0
and strings.ends_with(.scan.exiftool.zip_file_name, ".doc")
and .scan.exiftool.zip_uncompressed_size > 500000000
)
)
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 a potential Emotet delivery method using padded .doc files that compress into small zip files. Contents may include Red Dawn templates exceeding 500MB.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'zip'
any of
file.explode(.)where all hold:- .depth is 0
- .size < 1000000
not:
- .depth > 0
- .scan.exiftool.zip_file_name ends with '.doc'
- .scan.exiftool.zip_uncompressed_size > 500000000
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: attachments[].file_extension, type.inbound. Sensors: file.explode, profile.by_sender, strings.ends_with.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | zip |
strings.ends_with | suffix | .doc |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
not
file.explode(attachments[])[].depth gt "0"
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.exiftool.zip_file_name ends_with ".doc"
file.explode(attachments[])[].scan.exiftool.zip_uncompressed_size gt "500000000"
file.explode(attachments[])[].size lt "1000000"
attachments.file_extension eq "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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Employment contract update with suspicious file naming
#Detects messages containing two attachments where one is a PowerPoint file with suspicious character substitution in the filename ('Empl0yment' using zero instead of 'o') and body text claiming an employment contract has been updated.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// two attachments, one png and one pptx
and length(attachments) == 2
// the pptx has Empl0yment in name
and length(filter(attachments, strings.contains(.file_name, "Empl0yment"))) == 1
and strings.icontains(body.current_thread.text,
"Your Employment Contract has being updated"
)
Detection logic
Scope: inbound message.
Detects messages containing two attachments where one is a PowerPoint file with suspicious character substitution in the filename ('Empl0yment' using zero instead of 'o') and body text claiming an employment contract has been updated.
- inbound message
- length(attachments) is 2
- length(filter(attachments, strings.contains(.file_name, 'Empl0yment'))) is 1
- body.current_thread.text contains 'Your Employment Contract has being updated'
Inspects: attachments[].file_name, body.current_thread.text, type.inbound. Sensors: strings.contains, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | Empl0yment |
strings.icontains | substring | Your Employment Contract has being updated |
Stages and Predicates
Stage 1: mql_rule
and
attachments length_compare "2"
body.current_thread.text contains "Your Employment Contract has being updated"
filter(attachments, strings.contains(.file_name, 'Empl0yment')) length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains value:"Your Employment Contract has being updated" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Encrypted Microsoft Office file (unsolicited)
#Encrypted OLE2 (eg Microsoft Office) attachment from an unsolicited sender. Attachment encryption is a common technique used to bypass malware scanning products. Use if receiving encrypted attachments is not normal behavior in your environment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Macros, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and file.oletools(.).indicators.encryption.exists
)
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.
Encrypted OLE2 (eg Microsoft Office) attachment from an unsolicited sender. Attachment encryption is a common technique used to bypass malware scanning products. Use if receiving encrypted attachments is not normal behavior in your environment.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- file.oletools(.).indicators.encryption.exists
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.oletools, profile.by_sender. Reference lists: $file_extensions_macros.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
file.oletools func_call "file.oletools(attachments[]).indicators.encryption.exists"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Encrypted PDF With Credential Harvesting Indicators
#Detects encrypted PDF attachments containing patterns and indicators commonly associated with credential harvesting operations, identified through YARA signature analysis.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Encryption, Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("pdf_encrypted_cred_phish_001"))
)
)
Detection logic
Scope: inbound message.
Detects encrypted PDF attachments containing patterns and indicators commonly associated with credential harvesting operations, identified through YARA signature analysis.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_encrypted_cred_phish_001')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_encrypted_cred_phish_001 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_encrypted_cred_phish_001"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Encrypted PDF with credential theft body
#Attached PDF is encrypted, and email body contains credential theft language. Seen in-the-wild impersonating e-fax services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Encryption, Evasion, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.exiftool.fields, .key == "Encryption")
or (
.scan.entropy.entropy > 7
and any(.scan.strings.strings, strings.icontains(., "/Encrypt"))
)
)
// Encrypted PDFs do not have child nodes with any data
and all(filter(file.explode(.), .depth > 0), .size == 0)
)
and (
any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence in ("medium", "high")
)
or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
.name == "cred_theft" and .confidence in ("medium", "high")
)
or regex.icontains(body.current_thread.text,
'PDF\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))',
'(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
'(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)',
'The\s+(?:file|document|pdf|attachment)\s+(?:pass(?:code|word)|access\s*code)\s+is\s*'
)
or (
(
length(body.current_thread.text) <= 10
or (body.current_thread.text is null)
)
and any(body.previous_threads,
regex.icontains(.text,
'PDF\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))',
'(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
'(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)',
'The\s+(?:file|document|pdf|attachment)\s+(?:pass(?:code|word)|access\s*code)\s+is\s*'
)
)
)
)
// not forwards/replies
and not (
(length(headers.references) > 0 or headers.in_reply_to is not null)
and (subject.is_forward or subject.is_reply)
and length(body.previous_threads) >= 1
)
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 (
length(recipients.to) == 0
or all(recipients.to,
strings.ilike(.display_name, "undisclosed?recipients")
)
)
or (
length(recipients.to) == 1
and any(recipients.to, .email.email == sender.email.email)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
Detection logic
Scope: inbound message.
Attached PDF is encrypted, and email body contains credential theft language. Seen in-the-wild impersonating e-fax services.
- inbound message
any of
filter(attachments)where all hold:any of
file.explode(.)where any holds:any of
.scan.exiftool.fieldswhere:- .key is 'Encryption'
all of:
- .scan.entropy.entropy > 7
any of
.scan.strings.stringswhere:- . contains '/Encrypt'
all of
filter(...)where:- .size is 0
any of:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
any of
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
body.current_thread.text matches any of 5 patterns
PDF\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)The\s+(?:file|document|pdf|attachment)\s+(?:pass(?:code|word)|access\s*code)\s+is\s*
all of:
any of:
- length(body.current_thread.text) ≤ 10
- body.current_thread.text is missing
any of
body.previous_threadswhere:.text matches any of 5 patterns
PDF\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)The\s+(?:file|document|pdf|attachment)\s+(?:pass(?:code|word)|access\s*code)\s+is\s*
not:
all of:
any of:
- length(headers.references) > 0
- headers.in_reply_to is set
any of:
- subject.is_forward
- subject.is_reply
- length(body.previous_threads) ≥ 1
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
any of:
- length(recipients.to) is 0
all of
recipients.towhere:- .display_name matches 'undisclosed?recipients'
all of:
- length(recipients.to) is 1
any of
recipients.towhere:- .email.email is sender.email.email
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_type, body.current_thread.text, body.previous_threads, body.previous_threads[].text, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, recipients.to, recipients.to[].display_name, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, subject.is_forward, subject.is_reply, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.
Indicators matched (15)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.exiftool.fields[].key | equals | Encryption |
strings.icontains | substring | /Encrypt |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | member | medium |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | member | high |
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].name | equals | cred_theft |
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidence | member | medium |
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidence | member | high |
regex.icontains | regex | PDF\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word)) |
regex.icontains | regex | (Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*: |
regex.icontains | regex | This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:? |
3 more
regex.icontains | regex | (?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+) |
regex.icontains | regex | The\s+(?:file|document|pdf|attachment)\s+(?:pass(?:code|word)|access\s*code)\s+is\s* |
strings.ilike | substring | undisclosed?recipients |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(file.explode(filter(attachments)))
or
and
any(file.explode(filter(attachments)).scan.strings.strings)
file.explode(filter(attachments)).scan.strings.strings contains "/Encrypt"
file.explode(filter(attachments)[])[].scan.entropy.entropy gt "7"
any(file.explode(filter(attachments)).scan.exiftool.fields)
file.explode(filter(attachments)).scan.exiftool.fields.key eq "Encryption"
macro "all(filter(...))"
or
and
any(body.previous_threads)
or
body.previous_threads.text regex_match "(?:Access|Preview|Unlock|Decrypt)\\s+(?:\\S+\\s+){0,3}(?:PDF|statement)(?:\\S+\\s+){0,3}(?:pass(?:word|code)|\\s*with\\s+\\S+)"
body.previous_threads.text regex_match "(Access|Preview|Unlock|Decrypt|Pass)\\s*(?:word|code)\\s*(?:\\S+\\s+){0,3}PDF\\s*is?\\s*:"
body.previous_threads.text regex_match "PDF\\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))"
body.previous_threads.text regex_match "The\\s+(?:file|document|pdf|attachment)\\s+(?:pass(?:code|word)|access\\s*code)\\s+is\\s*"
body.previous_threads.text regex_match "This\\s+(?:file|document|pdf)\\s+is\\s+(?:password[-\\s]?)\\s+protected\\.\\s*The\\s+password\\s+is\\s*:?"
or
body.current_thread.text is_null
body.current_thread.text length_compare "10"
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 in ["high", "medium"]
ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
body.current_thread.text regex_match "(?:Access|Preview|Unlock|Decrypt)\\s+(?:\\S+\\s+){0,3}(?:PDF|statement)(?:\\S+\\s+){0,3}(?:pass(?:word|code)|\\s*with\\s+\\S+)"
body.current_thread.text regex_match "(Access|Preview|Unlock|Decrypt|Pass)\\s*(?:word|code)\\s*(?:\\S+\\s+){0,3}PDF\\s*is?\\s*:"
body.current_thread.text regex_match "PDF\\s*(?:Access|Preview|Unlock|Decrypt|pass(?:code|word))"
body.current_thread.text regex_match "The\\s+(?:file|document|pdf|attachment)\\s+(?:pass(?:code|word)|access\\s*code)\\s+is\\s*"
body.current_thread.text regex_match "This\\s+(?:file|document|pdf)\\s+is\\s+(?:password[-\\s]?)\\s+protected\\.\\s*The\\s+password\\s+is\\s*:?"
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
not
and
or
headers.in_reply_to is_not_null
headers.references length_compare "0"
or
subject.is_forward eq "true"
subject.is_reply eq "true"
body.previous_threads length_compare "1"
or
and
not
profile.by_sender_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
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)"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.in_reply_to | is_not_null | excludes:headers.in_reply_to | |
headers.references | length_compare | 0 | excludes:headers.references field:"headers.references" value:"0" |
subject.is_forward | eq | true | excludes:subject.is_forward field:"subject.is_forward" value:"true" |
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
body.previous_threads | length_compare | 1 | excludes:body.previous_threads field:"body.previous_threads" value:"1" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Encrypted PDF with credential theft language in EML
#Attached PDF is encrypted, and email body contains credential theft language, wrapped in an attached .eml file. Seen in-the-wild impersonating e-fax services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Encryption, Evasion, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
any(filter(file.parse_eml(.).attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.exiftool.fields, .key == "Encryption")
or (
.scan.entropy.entropy > 7
and any(.scan.strings.strings,
strings.icontains(., "/Encrypt")
)
)
)
// Encrypted PDFs do not have child nodes with any data
and all(filter(file.explode(.), .depth > 0), .size == 0)
)
and (
any(ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intents,
.name == "cred_theft" and .confidence in ("medium", "high")
)
or any(ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(.
).body.html
)
).text
).intents,
.name == "cred_theft" and .confidence in ("medium", "high")
)
or regex.icontains(file.parse_eml(.).body.current_thread.text,
'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
'(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
'(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
)
or (
(
length(file.parse_eml(.).body.current_thread.text) <= 10
or (file.parse_eml(.).body.current_thread.text is null)
)
and any(file.parse_eml(.).body.previous_threads,
regex.icontains(.text,
'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
'(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
'(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
)
)
)
)
)
// not forwards/replies
and not (
(length(headers.references) > 0 or headers.in_reply_to is not null)
and (subject.is_forward or subject.is_reply)
and length(body.previous_threads) >= 1
)
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 (
length(recipients.to) == 0
or (
all(recipients.to, .email.domain.valid == false)
and all(recipients.cc, .email.domain.valid == false)
)
)
or (
length(recipients.to) == 1
and any(recipients.to, .email.email == sender.email.email)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
and not (
sender.email.domain.root_domain in $high_trust_sender_root_domains
and coalesce(headers.auth_summary.dmarc.pass, false)
)
Detection logic
Scope: inbound message.
Attached PDF is encrypted, and email body contains credential theft language, wrapped in an attached .eml file. Seen in-the-wild impersonating e-fax services.
- inbound message
any of
attachmentswhere all hold:any of
filter(...)where all hold:any of
file.explode(.)where any holds:any of
.scan.exiftool.fieldswhere:- .key is 'Encryption'
all of:
- .scan.entropy.entropy > 7
any of
.scan.strings.stringswhere:- . contains '/Encrypt'
all of
filter(...)where:- .size is 0
any of:
any of
ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
any of
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(.).body.html)).text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
file.parse_eml(.).body.current_thread.text matches any of 4 patterns
PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)
all of:
any of:
- length(file.parse_eml(.).body.current_thread.text) ≤ 10
- file.parse_eml(.).body.current_thread.text is missing
any of
file.parse_eml(.).body.previous_threadswhere:.text matches any of 4 patterns
PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)
not:
all of:
any of:
- length(headers.references) > 0
- headers.in_reply_to is set
any of:
- subject.is_forward
- subject.is_reply
- length(body.previous_threads) ≥ 1
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
any of:
- length(recipients.to) is 0
all of:
all of
recipients.towhere:- .email.domain.valid is False
all of
recipients.ccwhere:- .email.domain.valid is False
all of:
- length(recipients.to) is 1
any of
recipients.towhere:- .email.email is sender.email.email
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, recipients.cc, recipients.cc[].email.domain.valid, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, subject.is_forward, subject.is_reply, type.inbound. Sensors: beta.ocr, file.explode, file.html_screenshot, file.parse_eml, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (13)
| Field | Match | Value |
|---|---|---|
file.parse_eml(attachments[]).attachments[].file_type | equals | pdf |
file.explode(filter(...)[])[].scan.exiftool.fields[].key | equals | Encryption |
strings.icontains | substring | /Encrypt |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].confidence | member | medium |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].confidence | member | high |
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments[]).body.html)).text).intents[].name | equals | cred_theft |
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments[]).body.html)).text).intents[].confidence | member | medium |
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments[]).body.html)).text).intents[].confidence | member | high |
regex.icontains | regex | PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode) |
regex.icontains | regex | (?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*: |
regex.icontains | regex | This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:? |
1 more
regex.icontains | regex | (?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(filter(...))
and
any(file.explode(filter(...)))
or
and
any(file.explode(filter(...)).scan.strings.strings)
file.explode(filter(...)).scan.strings.strings contains "/Encrypt"
file.explode(filter(...)[])[].scan.entropy.entropy gt "7"
any(file.explode(filter(...)).scan.exiftool.fields)
file.explode(filter(...)).scan.exiftool.fields.key eq "Encryption"
macro "all(filter(...))"
or
and
any(file.parse_eml(attachments).body.previous_threads)
or
file.parse_eml(attachments[]).body.previous_threads[].text regex_match "(?:Access|Preview|Unlock|Decrypt)\\s+(?:\\S+\\s+){0,3}(?:PDF|statement)(?:\\S+\\s+){0,3}(?:pass(?:word|code)|\\s*with\\s+\\S+)"
file.parse_eml(attachments[]).body.previous_threads[].text regex_match "(?:Access|Preview|Unlock|Decrypt|Pass)\\s*(?:word|code)\\s*(?:\\S+\\s+){0,3}PDF\\s*is?\\s*:"
file.parse_eml(attachments[]).body.previous_threads[].text regex_match "PDF\\s*(?:Access|Preview|Unlock|Decrypt|passcode)"
file.parse_eml(attachments[]).body.previous_threads[].text regex_match "This\\s+(?:file|document|pdf)\\s+is\\s+(?:password[-\\s]?)\\s+protected\\.\\s*The\\s+password\\s+is\\s*:?"
or
file.parse_eml(attachments[]).body.current_thread.text is_null
file.parse_eml(attachments[]).body.current_thread.text length_compare "10"
any(ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments).body.html)).text).intents)
and
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments[]).body.html)).text).intents[].confidence in ["high", "medium"]
ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(attachments[]).body.html)).text).intents[].name eq "cred_theft"
any(ml.nlu_classifier(file.parse_eml(attachments).body.current_thread.text).intents)
and
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].confidence in ["high", "medium"]
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].name eq "cred_theft"
file.parse_eml(attachments[]).body.current_thread.text regex_match "(?:Access|Preview|Unlock|Decrypt)\\s+(?:\\S+\\s+){0,3}(?:PDF|statement)(?:\\S+\\s+){0,3}(?:pass(?:word|code)|\\s*with\\s+\\S+)"
file.parse_eml(attachments[]).body.current_thread.text regex_match "(?:Access|Preview|Unlock|Decrypt|Pass)\\s*(?:word|code)\\s*(?:\\S+\\s+){0,3}PDF\\s*is?\\s*:"
file.parse_eml(attachments[]).body.current_thread.text regex_match "PDF\\s*(?:Access|Preview|Unlock|Decrypt|passcode)"
file.parse_eml(attachments[]).body.current_thread.text regex_match "This\\s+(?:file|document|pdf)\\s+is\\s+(?:password[-\\s]?)\\s+protected\\.\\s*The\\s+password\\s+is\\s*:?"
not
and
or
headers.in_reply_to is_not_null
headers.references length_compare "0"
or
subject.is_forward eq "true"
subject.is_reply eq "true"
body.previous_threads length_compare "1"
or
and
not
profile.by_sender_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
any(recipients.to)
recipients.to.email.email cross_field_compare "sender.email.email"
recipients.to length_compare "1"
and
macro "all(recipients.cc)"
macro "all(recipients.to)"
recipients.to length_compare "0"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.in_reply_to | is_not_null | excludes:headers.in_reply_to | |
headers.references | length_compare | 0 | excludes:headers.references field:"headers.references" value:"0" |
subject.is_forward | eq | true | excludes:subject.is_forward field:"subject.is_forward" value:"true" |
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
body.previous_threads | length_compare | 1 | excludes:body.previous_threads field:"body.previous_threads" value:"1" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Encrypted ZIP containing VHDX file
#Detects ZIP attachments that are encrypted and contain VHDX files, which may be used to bypass security controls or deliver malicious payloads.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "zip"),
any(file.explode(.),
.scan.zip.encrypted == true
and any(.scan.zip.all_paths, strings.ends_with(., "vhdx"))
)
)
Detection logic
Scope: inbound message.
Detects ZIP attachments that are encrypted and contain VHDX files, which may be used to bypass security controls or deliver malicious payloads.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .scan.zip.encrypted is True
any of
.scan.zip.all_pathswhere:- . ends with 'vhdx'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.ends_with.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | zip |
strings.ends_with | suffix | vhdx |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.zip.all_paths)
file.explode(filter(attachments)).scan.zip.all_paths ends_with "vhdx"
file.explode(filter(attachments)[])[].scan.zip.encrypted eq "true"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Excel file with document sharing lure created by Go Excelize
#Detects Excel macro files created with the Go Excelize library containing document sharing language such as 'sent document', 'shared file', or 'REVIEW DOCUMENT'. These files are often used as lures to trick users into enabling macros or downloading malicious content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Macros, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments,
.file_extension in $file_extensions_macros
// limit the size to reduce FPs, the larger the document, the more likely it is for FPs on benign automated reports
and .size < 2000000
),
any(file.explode(.),
// document sharing lure
(
length(.scan.strings.raw, ) < 1000
and regex.icontains(.scan.strings.raw,
'(?:sent|shared|forwarded|provided|invited|received)(?:\s+\w+){0,9}\s+(?:document|file|attachment)',
)
)
or strings.icontains(.scan.strings.raw,
'Please download this spreadsheet or SVG and click'
)
or (
length(.scan.strings.raw) < 500
and strings.contains(.scan.strings.raw, 'REVIEW DOCUMENT')
)
)
and beta.parse_exif(.).creator == "xuri"
and any(beta.parse_exif(.).fields,
.key == "Application" and .value == "Go Excelize"
)
)
Detection logic
Scope: inbound message.
Detects Excel macro files created with the Go Excelize library containing document sharing language such as 'sent document', 'shared file', or 'REVIEW DOCUMENT'. These files are often used as lures to trick users into enabling macros or downloading malicious content.
- inbound message
any of
filter(attachments)where all hold:any of
file.explode(.)where any holds:all of:
- length(.scan.strings.raw) < 1000
- .scan.strings.raw matches '(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)'
- .scan.strings.raw contains 'Please download this spreadsheet or SVG and click'
all of:
- length(.scan.strings.raw) < 500
- .scan.strings.raw contains 'REVIEW DOCUMENT'
- beta.parse_exif(.).creator is 'xuri'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Application'
- .value is 'Go Excelize'
Inspects: attachments[].file_extension, attachments[].size, type.inbound. Sensors: beta.parse_exif, file.explode, regex.icontains, strings.contains, strings.icontains. Reference lists: $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (?:sent|shared|forwarded|provided|invited|received)(?:\s+\w+){0,9}\s+(?:document|file|attachment) |
strings.icontains | substring | Please download this spreadsheet or SVG and click |
strings.contains | substring | REVIEW DOCUMENT |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | Application |
beta.parse_exif(filter(attachments)[]).fields[].value | equals | Go Excelize |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(file.explode(filter(attachments)))
or
and
file.explode(filter(attachments)[])[].scan.strings.raw contains "REVIEW DOCUMENT"
file.explode(filter(attachments)[])[].scan.strings.raw length_compare "500"
and
file.explode(filter(attachments)[])[].scan.strings.raw length_compare "1000"
file.explode(filter(attachments)[])[].scan.strings.raw regex_match "(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)"
file.explode(filter(attachments)[])[].scan.strings.raw contains "Please download this spreadsheet or SVG and click"
any(beta.parse_exif(filter(attachments)).fields)
and
beta.parse_exif(filter(attachments)[]).fields[].key eq "Application"
beta.parse_exif(filter(attachments)[]).fields[].value eq "Go Excelize"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).creator == xuri"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Excel file with suspicious template identifier
#Detects Excel attachments containing a specific template identifier (TM16390866) in the EXIF metadata, which may indicate malicious or suspicious document templates being used to distribute harmful content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "xlsx"
and any(beta.parse_exif(.).fields,
.key == "Template" and .value == "TM16390866"
)
)
Detection logic
Scope: inbound message.
Detects Excel attachments containing a specific template identifier (TM16390866) in the EXIF metadata, which may indicate malicious or suspicious document templates being used to distribute harmful content.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'xlsx'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Template'
- .value is 'TM16390866'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | xlsx |
beta.parse_exif(attachments[]).fields[].key | equals | Template |
beta.parse_exif(attachments[]).fields[].value | equals | TM16390866 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.parse_exif(attachments).fields)
and
beta.parse_exif(attachments[]).fields[].key eq "Template"
beta.parse_exif(attachments[]).fields[].value eq "TM16390866"
attachments.file_type eq "xlsx"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Excel Web Query File (IQY)
#Recursively scans files and archives to detect IQY files. Coercing a target user into providing credentials to an attacker-controlled web server, or for SMB relaying.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments, .file_extension =~ "iqy")
or (
any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "iqy")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect IQY files. Coercing a target user into providing credentials to an attacker-controlled web server, or for SMB relaying.
- inbound message
any of:
any of
attachmentswhere:- .file_extension is 'iqy'
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'iqy'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | iqy |
file.explode(attachments[])[].file_extension | equals | iqy |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "iqy"
macro "attachments[].file_extension in file_extensions_common_archives"
any(attachments)
attachments.file_extension eq "iqy"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake attachment image lure
#Message (or attached message) contains an image impersonating an Outlook attachment button.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, Image as content, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) < 15
and (
// fake file attachment preview in original email
any(attachments,
.file_type in $file_types_images
and (
any(ml.logo_detect(.).brands,
.name == "FakeAttachment" and .confidence == "high"
)
or (
.size < 30000
and any(file.explode(.),
strings.icontains(.scan.ocr.raw, 'sent you')
// the attached image includes a filesize string
and regex.icontains(.scan.ocr.raw,
'\b\d+.\d{1,2}\s?(k|m)b(\s|$)'
)
)
)
)
)
// message body/screenhot
or any(ml.logo_detect(file.message_screenshot()).brands,
.name == "FakeAttachment" and .confidence == "high"
)
// Suspicious table with file size indicators
or regex.contains(body.html.raw,
"<table[^>]*>.*?<img[^>]+src=[\"']cid:[^\"']+[\"'][^>]*>.*?\\.(pdf|doc(x)|xls(x)?).*?<font[^>]*>\\s*\\d{1,4}\\.\\d{1,2}\\s*k[bB]"
)
// fake file attachment preview in attached EML
or any(attachments,
(.content_type == "message/rfc822" or .file_extension == "eml")
and any(file.parse_eml(.).attachments,
.file_type in $file_types_images
and (
any(ml.logo_detect(.).brands, .name == "FakeAttachment")
or (
.size < 30000
and any(file.explode(.),
strings.icontains(.scan.ocr.raw, 'sent you')
// the attached image includes a filesize string
and regex.icontains(.scan.ocr.raw,
'\b\d+.\d{1,2}\s?(k|m)b(\s|$)'
)
)
)
)
)
)
)
and not (
(
strings.istarts_with(subject.subject, "RE:")
or strings.istarts_with(subject.subject, "R:")
or strings.istarts_with(subject.subject, "ODG:")
or strings.istarts_with(subject.subject, "答复:")
or strings.istarts_with(subject.subject, "AW:")
or strings.istarts_with(subject.subject, "TR:")
or strings.istarts_with(subject.subject, "FWD:")
or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
or regex.imatch(subject.subject,
'^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
)
)
and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
// 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 (
sender.email.domain.root_domain not in ("sharepointonline.com")
or not headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Message (or attached message) contains an image impersonating an Outlook attachment button.
- inbound message
- length(attachments) < 15
any of:
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of:
any of
ml.logo_detect(.).brandswhere all hold:- .name is 'FakeAttachment'
- .confidence is 'high'
all of:
- .size < 30000
any of
file.explode(.)where all hold:- .scan.ocr.raw contains 'sent you'
- .scan.ocr.raw matches '\\b\\d+.\\d{1,2}\\s?(k|m)b(\\s|$)'
any of
ml.logo_detect(file.message_screenshot()).brandswhere all hold:- .name is 'FakeAttachment'
- .confidence is 'high'
- body.html.raw matches '<table[^>]*>.*?<img[^>]+src=[\\"\']cid:[^\\"\']+[\\"\'][^>]*>.*?\\\\.(pdf|doc(x)|xls(x)?).*?<font[^>]*>\\\\s*\\\\d{1,4}\\\\.\\\\d{1,2}\\\\s*k[bB]'
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension is 'eml'
any of
file.parse_eml(.).attachmentswhere all hold:- .file_type in $file_types_images
any of:
any of
ml.logo_detect(.).brandswhere:- .name is 'FakeAttachment'
all of:
- .size < 30000
any of
file.explode(.)where all hold:- .scan.ocr.raw contains 'sent you'
- .scan.ocr.raw matches '\\b\\d+.\\d{1,2}\\s?(k|m)b(\\s|$)'
not:
all of:
any of:
- subject.subject starts with 'RE:'
- subject.subject starts with 'R:'
- subject.subject starts with 'ODG:'
- subject.subject starts with '答复:'
- subject.subject starts with 'AW:'
- subject.subject starts with 'TR:'
- subject.subject starts with 'FWD:'
- subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:'
- subject.subject matches '^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
any of:
- length(headers.references) > 0
- headers.in_reply_to is set
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
any of:
- sender.email.domain.root_domain not in ('sharepointonline.com')
not:
- headers.auth_summary.dmarc.pass
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, body.html.raw, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, file.parse_eml, ml.logo_detect, regex.contains, regex.icontains, regex.imatch, strings.icontains, strings.istarts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
ml.logo_detect(attachments[]).brands[].name | equals | FakeAttachment |
ml.logo_detect(attachments[]).brands[].confidence | equals | high |
strings.icontains | substring | sent you |
regex.icontains | regex | \b\d+.\d{1,2}\s?(k|m)b(\s|$) |
ml.logo_detect(file.message_screenshot()).brands[].name | equals | FakeAttachment |
ml.logo_detect(file.message_screenshot()).brands[].confidence | equals | high |
regex.contains | regex | <table[^>]*>.*?<img[^>]+src=[\"']cid:[^\"']+[\"'][^>]*>.*?\\.(pdf|doc(x)|xls(x)?).*?<font[^>]*>\\s*\\d{1,4}\\.\\d{1,2}\\s*k[bB] |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
ml.logo_detect(file.parse_eml(attachments[]).attachments[]).brands[].name | equals | FakeAttachment |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
and
any(file.parse_eml(attachments).attachments)
and
or
and
any(file.explode(file.parse_eml(attachments).attachments))
and
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.ocr.raw contains "sent you"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.ocr.raw regex_match "\\b\\d+.\\d{1,2}\\s?(k|m)b(\\s|$)"
file.parse_eml(attachments[]).attachments[].size lt "30000"
any(ml.logo_detect(file.parse_eml(attachments).attachments).brands)
ml.logo_detect(file.parse_eml(attachments).attachments).brands.name eq "FakeAttachment"
macro "file.parse_eml(attachments[]).attachments[].file_type in file_types_images"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
any(attachments)
and
or
and
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.ocr.raw contains "sent you"
file.explode(attachments[])[].scan.ocr.raw regex_match "\\b\\d+.\\d{1,2}\\s?(k|m)b(\\s|$)"
attachments.size lt "30000"
any(ml.logo_detect(attachments).brands)
and
ml.logo_detect(attachments[]).brands[].confidence eq "high"
ml.logo_detect(attachments[]).brands[].name eq "FakeAttachment"
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 eq "high"
ml.logo_detect(file.message_screenshot()).brands.name eq "FakeAttachment"
body.html.raw regex_match "<table[^>]*>.*?<img[^>]+src=[\\\"']cid:[^\\\"']+[\\\"'][^>]*>.*?\\\\.(pdf|doc(x)|xls(x)?).*?<font[^>]*>\\\\s*\\\\d{1,4}\\\\.\\\\d{1,2}\\\\s*k[bB]"
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 regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:"
subject.subject regex_match "^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
subject.subject starts_with "AW:"
subject.subject starts_with "FWD:"
subject.subject starts_with "ODG:"
subject.subject starts_with "R:"
subject.subject starts_with "RE:"
subject.subject starts_with "TR:"
subject.subject starts_with "答复:"
or
not
headers.auth_summary.dmarc.pass eq "true"
not
sender.email.domain.root_domain eq "sharepointonline.com"
attachments length_compare "15"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.html.raw | regex_match |
| field:"body.html.raw" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake lawyer & sports agent identities
#Detects messages containing attachments or content that reference known fake identities used in FC Barcelona scams, including fake lawyer Michael Gerardus Hermanus Demon and sports agents with the surname Giuffrida. The rule examines EXIF metadata, OCR text from attachments, and message body content for these specific identity markers.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Impersonation: VIP, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and beta.parse_exif(attachments[0]).creator == "Gabriele Giuffrida"
Detection logic
Scope: inbound message.
Detects messages containing attachments or content that reference known fake identities used in FC Barcelona scams, including fake lawyer Michael Gerardus Hermanus Demon and sports agents with the surname Giuffrida. The rule examines EXIF metadata, OCR text from attachments, and message body content for these specific identity markers.
- inbound message
- length(attachments) is 1
- beta.parse_exif(attachments[0]).creator is 'Gabriele Giuffrida'
Inspects: attachments[0], type.inbound. Sensors: beta.parse_exif.
Stages and Predicates
Stage 1: mql_rule
and
attachments length_compare "1"
beta.parse_exif func_call "beta.parse_exif(attachments[0]).creator == Gabriele Giuffrida"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake PDF Invoices Yara
#These yara signatures match fake invoice PDFs with specific artifiacts including images and link locations.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name in (
"fake_invoice_pdf_structure_01",
"fake_invoice_pdf_images_01",
)
)
)
)
Detection logic
Scope: inbound message.
These yara signatures match fake invoice PDFs with specific artifiacts including images and link locations.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('fake_invoice_pdf_structure_01', 'fake_invoice_pdf_images_01')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | fake_invoice_pdf_structure_01 |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | fake_invoice_pdf_images_01 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name in ["fake_invoice_pdf_images_01", "fake_invoice_pdf_structure_01"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake scan-to-email
#Message and attachment resemble an email from a scan-to-email service or device with credential theft language.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free file host, Image as content, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
length(body.current_thread.text) < 1500
// body length without disclaimer is shorter than 1500 characters
or (
any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
.name == "disclaimer"
),
.text
),
(length(body.current_thread.text) - length(.)) < 1500
)
)
)
and (
3 of (
strings.icontains(body.current_thread.text, "Number of Images:"),
strings.icontains(body.current_thread.text, "Attachment File Type:"),
strings.icontains(body.current_thread.text, "Device Model:"),
strings.icontains(body.current_thread.text, "Device Name:"),
strings.icontains(body.current_thread.text, "Resolution:"),
strings.icontains(body.current_thread.text, "File Format:"),
strings.icontains(body.current_thread.text, "Device Location:")
)
or (
3 of (
strings.ilike(body.current_thread.text, "*scan date*"),
strings.ilike(body.current_thread.text, "*was sent from*"),
strings.ilike(body.current_thread.text, "*of pages*"),
strings.ilike(body.current_thread.text, "*scanned file*"),
)
or any(file.explode(file.message_screenshot()),
3 of (
strings.ilike(body.current_thread.text, "*scan date*"),
strings.ilike(body.current_thread.text, "*was sent from*"),
strings.ilike(body.current_thread.text, "*of pages*"),
strings.ilike(body.current_thread.text, "*scanned file*"),
strings.icontains(body.current_thread.text, "Number of Images:"),
strings.icontains(body.current_thread.text,
"Attachment File Type:"
),
strings.icontains(body.current_thread.text, "Device Name:"),
strings.icontains(body.current_thread.text, "Device Location:"),
strings.icontains(body.current_thread.text, "Device Model:")
)
)
)
)
and (
(
length(filter(attachments, .file_type in ("pdf"))) == 1
and any(attachments,
.file_type == "pdf"
and (
any(file.explode(.),
(
strings.ilike(.scan.ocr.raw,
"*scan date*",
"*was sent from*",
"*of pages*",
"*verif*document*",
"*scanned file*"
)
or any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft"
)
or any(ml.logo_detect(..).brands,
.name in ("DocuSign", "Microsoft")
)
)
and length(.scan.url.urls) == 1
)
// encrypted pdf
or any(file.explode(.),
any(.scan.exiftool.fields, .key == "Encryption")
or (
.scan.entropy.entropy > 7
and any(.scan.strings.strings,
strings.icontains(., "/Encrypt")
)
)
)
)
)
)
or length(filter(attachments, .file_type in ("doc", "docx"))) == 1
)
and sender.email.domain.domain not in~ $org_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.
Message and attachment resemble an email from a scan-to-email service or device with credential theft language.
- inbound message
any of:
- length(body.current_thread.text) < 1500
any of
map(...)where:- length(body.current_thread.text) - length(.) < 1500
any of:
at least 3 of 7: body.current_thread.text contains any of 7 patterns
Number of Images:Attachment File Type:Device Model:Device Name:Resolution:File Format:Device Location:
any of:
at least 3 of 4: body.current_thread.text matches any of 4 patterns
*scan date**was sent from**of pages**scanned file*
any of
file.explode(...)where:at least 3 of:
- body.current_thread.text matches '*scan date*'
- body.current_thread.text matches '*was sent from*'
- body.current_thread.text matches '*of pages*'
- body.current_thread.text matches '*scanned file*'
- body.current_thread.text contains 'Number of Images:'
- body.current_thread.text contains 'Attachment File Type:'
- body.current_thread.text contains 'Device Name:'
- body.current_thread.text contains 'Device Location:'
- body.current_thread.text contains 'Device Model:'
any of:
all of:
- length(filter(attachments, .file_type in ('pdf'))) is 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of:
any of
file.explode(.)where all hold:any of:
.scan.ocr.raw matches any of 5 patterns
*scan date**was sent from**of pages**verif*document**scanned file*
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere:- .name is 'cred_theft'
any of
ml.logo_detect(.).brandswhere:- .name in ('DocuSign', 'Microsoft')
- length(.scan.url.urls) is 1
any of
file.explode(.)where any holds:any of
.scan.exiftool.fieldswhere:- .key is 'Encryption'
all of:
- .scan.entropy.entropy > 7
any of
.scan.strings.stringswhere:- . contains '/Encrypt'
- length(filter(attachments, .file_type in ('doc', 'docx'))) is 1
- sender.email.domain.domain not in $org_domains
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_type, body.current_thread.text, sender.email.domain.domain, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, strings.icontains, strings.ilike. Reference lists: $org_domains.
Indicators matched (22)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | disclaimer |
strings.icontains | substring | Number of Images: |
strings.icontains | substring | Attachment File Type: |
strings.icontains | substring | Device Model: |
strings.icontains | substring | Device Name: |
strings.icontains | substring | Resolution: |
strings.icontains | substring | File Format: |
strings.icontains | substring | Device Location: |
strings.ilike | substring | *scan date* |
strings.ilike | substring | *was sent from* |
strings.ilike | substring | *of pages* |
strings.ilike | substring | *scanned file* |
10 more
attachments[].file_type | member | pdf |
attachments[].file_type | equals | pdf |
strings.ilike | substring | *verif*document* |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.logo_detect(attachments[]).brands[].name | member | DocuSign |
ml.logo_detect(attachments[]).brands[].name | member | Microsoft |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | Encryption |
strings.icontains | substring | /Encrypt |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
Stages and Predicates
Stage 1: mql_rule
and
or
and
any(attachments)
and
or
any(file.explode(attachments))
or
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "/Encrypt"
file.explode(attachments[])[].scan.entropy.entropy gt "7"
any(file.explode(attachments).scan.exiftool.fields)
file.explode(attachments).scan.exiftool.fields.key eq "Encryption"
any(file.explode(attachments))
and
or
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name in ["DocuSign", "Microsoft"]
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"
file.explode(attachments[])[].scan.ocr.raw match "of pages"
file.explode(attachments[])[].scan.ocr.raw match "scan date"
file.explode(attachments[])[].scan.ocr.raw match "scanned file"
file.explode(attachments[])[].scan.ocr.raw match "was sent from"
file.explode(attachments[])[].scan.ocr.raw wildcard "*verif*document*"
file.explode(attachments[])[].scan.url.urls length_compare "1"
attachments.file_type eq "pdf"
filter(attachments, .file_type in ('pdf')) length_compare "1"
filter(attachments, .file_type in ('doc', 'docx')) length_compare "1"
or
any(file.explode(...))
or
body.current_thread.text contains "Attachment File Type:"
body.current_thread.text contains "Device Location:"
body.current_thread.text contains "Device Model:"
body.current_thread.text contains "Device Name:"
body.current_thread.text contains "Number of Images:"
body.current_thread.text match "of pages"
body.current_thread.text match "scan date"
body.current_thread.text match "scanned file"
body.current_thread.text match "was sent from"
body.current_thread.text contains "Attachment File Type:"
body.current_thread.text contains "Device Location:"
body.current_thread.text contains "Device Model:"
body.current_thread.text contains "Device Name:"
body.current_thread.text contains "File Format:"
body.current_thread.text contains "Number of Images:"
body.current_thread.text contains "Resolution:"
body.current_thread.text match "of pages"
body.current_thread.text match "scan date"
body.current_thread.text match "scanned file"
body.current_thread.text match "was sent from"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
any(map(...))
macro "(length(body.current_thread.text) - length(map(...)[])) < 1500"
body.current_thread.text length_compare "1500"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
type.inbound eq "true"
macro "sender.email.domain.domain not in org_domains"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains |
body.current_thread.text | wildcard |
| field:"body.current_thread.text" kind:wildcard |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake secure message and suspicious indicators
#Body contains language resembling credential theft, and an attached "secure message" from an untrusted sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Image as content, Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence == "high"
)
// ----- other suspicious signals here -----
and any(attachments,
any(file.explode(.),
any(.scan.strings.strings, strings.icontains(., "secure message"))
and (
any(.scan.url.urls, .domain.tld in $suspicious_tlds)
or any(.scan.url.urls,
any(.rewrite.encoders,
strings.icontains(., "open_redirect")
)
)
)
and (
any(.scan.url.urls,
.domain.root_domain != sender.email.domain.root_domain
)
or not sender.email.domain.valid
)
)
)
// negate legitimate message senders
and (
(
sender.email.domain.root_domain not in ("protectedtrust.com")
or not sender.email.domain.valid
)
and any(headers.hops,
.index == 0
and not any(.fields,
strings.contains(.value,
'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
)
)
)
and not (
any(headers.hops, any(.fields, .name == 'X-ZixNet'))
and any(headers.domains,
.root_domain in ("zixport.com", "zixcorp.com", "zixmail.net")
)
)
and not all(body.links,
.href_url.domain.root_domain in ("mimecast.com", "cisco.com")
)
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
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.
Body contains language resembling credential theft, and an attached "secure message" from an untrusted sender.
- inbound message
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
any of
attachmentswhere:any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . contains 'secure message'
any of:
any of
.scan.url.urlswhere:- .domain.tld in $suspicious_tlds
any of
.scan.url.urlswhere:any of
.rewrite.encoderswhere:- . contains 'open_redirect'
any of:
any of
.scan.url.urlswhere:- .domain.root_domain is not sender.email.domain.root_domain
not:
- sender.email.domain.valid
all of:
any of:
- sender.email.domain.root_domain not in ('protectedtrust.com')
not:
- sender.email.domain.valid
any of
headers.hopswhere all hold:- .index is 0
not:
any of
.fieldswhere:- .value contains 'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
not:
all of:
any of
headers.hopswhere:any of
.fieldswhere:- .name is 'X-ZixNet'
any of
headers.domainswhere:- .root_domain in ('zixport.com', 'zixcorp.com', 'zixmail.net')
not:
all of
body.linkswhere:- .href_url.domain.root_domain in ('mimecast.com', 'cisco.com')
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
not:
- profile.by_sender().any_messages_benign
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.root_domain, 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, sender.email.domain.root_domain, sender.email.domain.valid, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender, strings.contains, strings.icontains. Reference lists: $high_trust_sender_root_domains, $suspicious_tlds.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | equals | high |
strings.icontains | substring | secure message |
strings.icontains | substring | open_redirect |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.url.urls)
any(file.explode(attachments).scan.url.urls.rewrite.encoders)
file.explode(attachments).scan.url.urls.rewrite.encoders contains "open_redirect"
any(file.explode(attachments).scan.url.urls)
macro "file.explode(attachments[])[].scan.url.urls[].domain.tld in suspicious_tlds"
or
any(file.explode(attachments).scan.url.urls)
file.explode(attachments).scan.url.urls.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
not
sender.email.domain.valid eq "true"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "secure message"
not
and
any(headers.hops)
any(headers.hops.fields)
headers.hops.fields.name eq "X-ZixNet"
any(headers.domains)
headers.domains.root_domain in ["zixcorp.com", "zixmail.net", "zixport.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
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)"
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
not
sender.email.domain.root_domain eq "protectedtrust.com"
not
sender.email.domain.valid eq "true"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
not
macro "all(body.links)"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
headers.domains | array_any | excludes:headers.domains |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake Slack installer
#HTML attachment contains a Slack logo, request language, and a link to an executable. Observed in the wild.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Impersonation: Brand, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
or .content_type == "text/html"
)
and any(ml.logo_detect(file.html_screenshot(.)).brands,
.name == "Slack" and .confidence in ("medium", "high")
)
and any(ml.nlu_classifier(file.parse_html(.).display_text).entities,
.name == "request" and .text =~ "download"
)
and any(file.explode(.),
any(.scan.url.urls,
strings.iends_with(.path, ".exe")
and .domain.root_domain not in $org_domains
)
)
)
)
Detection logic
Scope: inbound message.
HTML attachment contains a Slack logo, request language, and a link to an executable. Observed in the wild.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
- .content_type is 'text/html'
any of
ml.logo_detect(file.html_screenshot(.)).brandswhere all hold:- .name is 'Slack'
- .confidence in ('medium', 'high')
any of
ml.nlu_classifier(file.parse_html(.).display_text).entitieswhere all hold:- .name is 'request'
- .text is 'download'
any of
file.explode(.)where:any of
.scan.url.urlswhere all hold:- .path ends with '.exe'
- .domain.root_domain not in $org_domains
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, file.html_screenshot, file.parse_html, ml.logo_detect, ml.nlu_classifier, strings.iends_with. Reference lists: $org_domains.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].name | equals | Slack |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidence | member | medium |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidence | member | high |
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].name | equals | request |
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].text | equals | download |
strings.iends_with | suffix | .exe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
file.explode(attachments[])[].scan.url.urls[].path ends_with ".exe"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in org_domains"
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 "Slack"
any(ml.nlu_classifier(file.parse_html(attachments).display_text).entities)
and
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].name eq "request"
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].text eq "download"
or
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake voicemail via PDF
#Identifies inbound messages containing a single-page PDF attachment related to voicemail or missed call notifications that includes either a URL or QR code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// a single PDF attachment
and length(attachments) == 1
// the subject doesn't contain fax, which is currently a common match for the topic
and not strings.icontains(subject.base, 'fax')
and (
length(body.current_thread.text) == 0
or (
ml.nlu_classifier(body.current_thread.text).language == "english"
and (
any(ml.nlu_classifier(body.current_thread.text).topics,
.confidence == "high"
and .name == "Voicemail Call and Missed Call Notifications"
)
or any(ml.nlu_classifier(body.current_thread.text).intents,
.confidence == "high" and .name == "bec"
)
)
)
)
// the Topic analysis of the PDF is Voicemail
and any(attachments,
.file_extension == "pdf"
// the NLU detected language is english
and ml.nlu_classifier(beta.ocr(.).text).language == "english"
and length(beta.ocr(.).text) > 95
and any(ml.nlu_classifier(beta.ocr(.).text).topics,
.confidence == "high"
and .name == "Voicemail Call and Missed Call Notifications"
)
and beta.ocr(.).success
// contains a link or QR code
and any(file.explode(.),
0 < length(.scan.pdf.urls) <= 2 or .scan.qr.url.url is not null
)
// there is only a single page
and any(file.explode(.), .depth == 0 and .scan.exiftool.page_count == 1)
)
and not (
sender.email.domain.root_domain == "zendesk.com"
and coalesce(headers.auth_summary.dmarc.pass, false)
)
Detection logic
Scope: inbound message.
Identifies inbound messages containing a single-page PDF attachment related to voicemail or missed call notifications that includes either a URL or QR code.
- inbound message
- length(attachments) is 1
not:
- subject.base contains 'fax'
any of:
- length(body.current_thread.text) is 0
all of:
- ml.nlu_classifier(body.current_thread.text).language is 'english'
any of:
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .confidence is 'high'
- .name is 'Voicemail Call and Missed Call Notifications'
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .confidence is 'high'
- .name is 'bec'
any of
attachmentswhere all hold:- .file_extension is 'pdf'
- ml.nlu_classifier(beta.ocr(.).text).language is 'english'
- length(beta.ocr(.).text) > 95
any of
ml.nlu_classifier(beta.ocr(.).text).topicswhere all hold:- .confidence is 'high'
- .name is 'Voicemail Call and Missed Call Notifications'
- beta.ocr(.).success
any of
file.explode(.)where any holds:all of:
- length(.scan.pdf.urls) > 0
- length(.scan.pdf.urls) ≤ 2
- .scan.qr.url.url is set
any of
file.explode(.)where all hold:- .depth is 0
- .scan.exiftool.page_count is 1
not:
all of:
- sender.email.domain.root_domain is 'zendesk.com'
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: beta.ocr, file.explode, ml.nlu_classifier, strings.icontains.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).topics[].confidence | equals | high |
ml.nlu_classifier(body.current_thread.text).topics[].name | equals | Voicemail Call and Missed Call Notifications |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | equals | high |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | bec |
attachments[].file_extension | equals | pdf |
ml.nlu_classifier(beta.ocr(attachments[]).text).topics[].confidence | equals | high |
ml.nlu_classifier(beta.ocr(attachments[]).text).topics[].name | equals | Voicemail Call and Missed Call Notifications |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
file.explode(attachments[])[].scan.pdf.urls length_compare "0"
file.explode(attachments[])[].scan.pdf.urls length_compare "2"
file.explode(attachments[])[].scan.qr.url.url is_not_null
any(file.explode(attachments))
and
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.exiftool.page_count eq "1"
any(ml.nlu_classifier(beta.ocr(attachments).text).topics)
and
ml.nlu_classifier(beta.ocr(attachments[]).text).topics[].confidence eq "high"
ml.nlu_classifier(beta.ocr(attachments[]).text).topics[].name eq "Voicemail Call and Missed Call Notifications"
attachments.file_extension eq "pdf"
beta.ocr func_call "beta.ocr(attachments[]).success"
beta.ocr(attachments[]).text length_compare "95"
ml.nlu_classifier func_call "ml.nlu_classifier(beta.ocr(attachments[]).text).language == english"
or
and
or
any(ml.nlu_classifier(body.current_thread.text).intents)
and
ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
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 "Voicemail Call and Missed Call Notifications"
ml.nlu_classifier func_call "ml.nlu_classifier(body.current_thread.text).language == english"
body.current_thread.text length_compare "0"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
sender.email.domain.root_domain eq "zendesk.com"
not
subject.base contains "fax"
attachments length_compare "1"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | eq | zendesk.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"zendesk.com" |
subject.base | contains | fax | excludes:subject.base field:"subject.base" value:"fax" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Fake Zoom installer
#HTML attachment contains a Zoom logo, request language, and a link to an executable. Observed in the wild.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Impersonation: Brand, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
or .content_type == "text/html"
)
and any(ml.logo_detect(file.html_screenshot(.)).brands,
.name == "Zoom" and .confidence in ("medium", "high")
)
and any(ml.nlu_classifier(file.parse_html(.).display_text).entities,
.name == "request" and .text =~ "download"
)
and any(file.explode(.),
any(.scan.url.urls,
strings.iends_with(.path, ".exe")
and .domain.root_domain not in $org_domains
)
)
)
Detection logic
Scope: inbound message.
HTML attachment contains a Zoom logo, request language, and a link to an executable. Observed in the wild.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
- .content_type is 'text/html'
any of
ml.logo_detect(file.html_screenshot(.)).brandswhere all hold:- .name is 'Zoom'
- .confidence in ('medium', 'high')
any of
ml.nlu_classifier(file.parse_html(.).display_text).entitieswhere all hold:- .name is 'request'
- .text is 'download'
any of
file.explode(.)where:any of
.scan.url.urlswhere all hold:- .path ends with '.exe'
- .domain.root_domain not in $org_domains
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, file.html_screenshot, file.parse_html, ml.logo_detect, ml.nlu_classifier, strings.iends_with. Reference lists: $org_domains.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].name | equals | Zoom |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidence | member | medium |
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidence | member | high |
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].name | equals | request |
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].text | equals | download |
strings.iends_with | suffix | .exe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
file.explode(attachments[])[].scan.url.urls[].path ends_with ".exe"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in org_domains"
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 "Zoom"
any(ml.nlu_classifier(file.parse_html(attachments).display_text).entities)
and
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].name eq "request"
ml.nlu_classifier(file.parse_html(attachments[]).display_text).entities[].text eq "download"
or
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: File execution via Javascript
#Javascript contains identifiers or strings that may attempt to execute files.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type in $file_extensions_common_archives
and any(file.explode(.),
any(.scan.javascript.identifiers,
strings.ilike(., 'ActiveXObject', 'ShellExecute')
)
or (
length(.scan.javascript.strings) > 0
and all(.scan.javascript.strings,
strings.ilike(., 'Shell.Application', '*.exe')
)
)
)
)
Detection logic
Scope: inbound message.
Javascript contains identifiers or strings that may attempt to execute files.
- inbound message
any of
attachmentswhere all hold:- .file_type in $file_extensions_common_archives
any of
file.explode(.)where any holds:any of
.scan.javascript.identifierswhere:. matches any of 2 patterns
ActiveXObjectShellExecute
all of:
- length(.scan.javascript.strings) > 0
all of
.scan.javascript.stringswhere:. matches any of 2 patterns
Shell.Application*.exe
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
strings.ilike | substring | ActiveXObject |
strings.ilike | substring | ShellExecute |
strings.ilike | substring | Shell.Application |
strings.ilike | substring | *.exe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.javascript.identifiers)
or
file.explode(attachments[])[].scan.javascript.identifiers[] eq "ActiveXObject"
file.explode(attachments[])[].scan.javascript.identifiers[] eq "ShellExecute"
and
file.explode(attachments[])[].scan.javascript.strings length_compare "0"
macro "all(file.explode(attachments[])[].scan.javascript.strings)"
macro "attachments[].file_type in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Filename containing Unicode braille pattern blank character
#Recursively identifies attachments that attempt to conceal their true file extension by using Braille Pattern Blank characters
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
regex.icontains(.file_name, '\x{2800}')
or (
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), regex.icontains(.file_name, '\x{2800}'))
)
)
Detection logic
Scope: inbound message.
Recursively identifies attachments that attempt to conceal their true file extension by using Braille Pattern Blank characters
- inbound message
any of
attachmentswhere any holds:- .file_name matches '\\x{2800}'
all of:
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_name matches '\\x{2800}'
Inspects: attachments[].file_extension, attachments[].file_name, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | \x{2800} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
file.explode(attachments).file_name regex_match "\\x{2800}"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.file_name regex_match "\\x{2800}"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Filename containing Unicode right-to-left override character
#Recursively identifies attachments that attempt to conceal their true file extension by using right-to-left override characters
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
regex.icontains(.file_name, '\x{202E}', '\x{202D}')
or (
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.),
regex.icontains(.file_name, '\x{202E}', '\x{202D}')
)
)
)
Detection logic
Scope: inbound message.
Recursively identifies attachments that attempt to conceal their true file extension by using right-to-left override characters
- inbound message
any of
attachmentswhere any holds:.file_name matches any of 2 patterns
\x{202E}\x{202D}
all of:
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:.file_name matches any of 2 patterns
\x{202E}\x{202D}
Inspects: attachments[].file_extension, attachments[].file_name, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | \x{202E} |
regex.icontains | regex | \x{202D} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
or
file.explode(attachments[])[].file_name regex_match "\\x{202D}"
file.explode(attachments[])[].file_name regex_match "\\x{202E}"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.file_name regex_match "\\x{202D}"
attachments.file_name regex_match "\\x{202E}"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Finance themed PDF with observed phishing template
#Detects PDF attachments containing a specific rectangular coordinate pattern at position [249.75 560 407.25 599.75], which may indicate a templated or malicious document structure.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.strings.strings,
strings.contains(., "/Rect [ 249.75 560 407.25 599.75 ]")
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a specific rectangular coordinate pattern at position [249.75 560 407.25 599.75], which may indicate a templated or malicious document structure.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . contains '/Rect [ 249.75 560 407.25 599.75 ]'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.contains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.contains | substring | /Rect [ 249.75 560 407.25 599.75 ] |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.strings.strings)
file.explode(filter(attachments)).scan.strings.strings contains "/Rect [ 249.75 560 407.25 599.75 ]"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML attachment with Javascript location
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and .size <= 5000
and any(file.explode(.),
any(.scan.javascript.identifiers, . == "location")
and length(.scan.javascript.identifiers) < 100
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .size ≤ 5000
any of
file.explode(.)where all hold:any of
.scan.javascript.identifierswhere:- . is 'location'
- length(.scan.javascript.identifiers) < 100
Inspects: attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].scan.javascript.identifiers[] | equals | location |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers eq "location"
file.explode(attachments[])[].scan.javascript.identifiers length_compare "100"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.size le "5000"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML attachment with login portal indicators
#Recursively scans files and archives to detect indicators of login portals implemented in HTML files. This is a known credential theft technique used by threat actors.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
// suspicious strings found in javascript
(
length(filter(.scan.javascript.strings,
strings.ilike(., "*password*", )
)
) >= 2
and 2 of (
any(.scan.javascript.strings,
strings.ilike(., "*incorrect*")
),
any(.scan.javascript.strings, strings.ilike(., "*invalid*")),
any(.scan.javascript.strings, strings.ilike(., "*login*")),
any(.scan.javascript.strings, regex.icontains(., "sign.in")),
)
)
or (
// suspicious strings found outside of javascript, but binexplode'd file still of HTML type
length(filter(.scan.strings.strings,
strings.ilike(., "*password*", )
)
) >= 2
and 2 of (
any(.scan.strings.strings, strings.ilike(., "*incorrect*")),
any(.scan.strings.strings, strings.ilike(., "*invalid*")),
any(.scan.strings.strings, strings.ilike(., "*login*")),
any(.scan.strings.strings, strings.ilike(., "*<script>*")),
any(.scan.strings.strings, regex.icontains(., "sign.in")),
any(.scan.strings.strings,
regex.icontains(.,
'<title>.[^<]+(Payment|Invoice|Statement|Login|Microsoft|Email|Excel)'
)
)
)
)
or
// Known phishing obfuscation
2 of (
// Enter password
any(.scan.strings.strings,
strings.ilike(.,
"*&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*"
)
),
// Forgotten my password
any(.scan.strings.strings,
strings.ilike(.,
"*&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*"
)
),
// Sign in
any(.scan.strings.strings,
strings.ilike(.,
"*&#83;&#105;&#103;&#110;&#32;&#105;&#110*"
)
)
)
)
)
and (
(
// exclude internal mailers where there is no SPF configured.
// if the sender's root domain is an org domain, we
// ensure there's an SPF pass
// we use root_domain because it's typically subdomains that are misconfigured
sender.email.domain.root_domain in $org_domains
and headers.auth_summary.spf.pass
)
or sender.email.domain.root_domain not in $org_domains
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
and (
(
not profile.by_sender().solicited
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.
Recursively scans files and archives to detect indicators of login portals implemented in HTML files. This is a known credential theft technique used by threat actors.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where any holds:all of:
- length(filter(.scan.javascript.strings, strings.ilike(., '*password*'))) ≥ 2
at least 2 of:
any of
.scan.javascript.stringswhere:- . matches '*incorrect*'
any of
.scan.javascript.stringswhere:- . matches '*invalid*'
any of
.scan.javascript.stringswhere:- . matches '*login*'
any of
.scan.javascript.stringswhere:- . matches 'sign.in'
all of:
- length(filter(.scan.strings.strings, strings.ilike(., '*password*'))) ≥ 2
at least 2 of:
any of
.scan.strings.stringswhere:- . matches '*incorrect*'
any of
.scan.strings.stringswhere:- . matches '*invalid*'
any of
.scan.strings.stringswhere:- . matches '*login*'
any of
.scan.strings.stringswhere:- . matches '*<script>*'
any of
.scan.strings.stringswhere:- . matches 'sign.in'
any of
.scan.strings.stringswhere:- . matches '<title>.[^<]+(Payment|Invoice|Statement|Login|Microsoft|Email|Excel)'
at least 2 of:
any of
.scan.strings.stringswhere:- . matches '*&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*'
any of
.scan.strings.stringswhere:- . matches '*&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100*'
any of
.scan.strings.stringswhere:- . matches '*&#83;&#105;&#103;&#110;&#32;&#105;&#110*'
any of:
all of:
- sender.email.domain.root_domain in $org_domains
- headers.auth_summary.spf.pass
- sender.email.domain.root_domain not in $org_domains
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
any of:
all 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
Inspects: attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, profile.by_sender, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains, $org_domains.
Indicators matched (15)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
strings.ilike | substring | *password* |
strings.ilike | substring | *incorrect* |
strings.ilike | substring | *invalid* |
strings.ilike | substring | *login* |
regex.icontains | regex | sign.in |
strings.ilike | substring | *<script>* |
regex.icontains | regex | <title>.[^<]+(Payment|Invoice|Statement|Login|Microsoft|Email|Excel) |
3 more
strings.ilike | substring | *&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100* |
strings.ilike | substring | *&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100* |
strings.ilike | substring | *&#83;&#105;&#103;&#110;&#32;&#105;&#110* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
or
any(file.explode(attachments).scan.javascript.strings)
file.explode(attachments).scan.javascript.strings match "incorrect"
any(file.explode(attachments).scan.javascript.strings)
file.explode(attachments).scan.javascript.strings match "invalid"
any(file.explode(attachments).scan.javascript.strings)
file.explode(attachments).scan.javascript.strings match "login"
any(file.explode(attachments).scan.javascript.strings)
file.explode(attachments).scan.javascript.strings regex_match "sign.in"
filter(file.explode(attachments[])[].scan.javascript.strings, strings.ilike(file.explode(attachments[])[], '*password*')) length_compare "2"
and
or
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "<script>"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "incorrect"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "invalid"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "login"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "<title>.[^<]+(Payment|Invoice|Statement|Login|Microsoft|Email|Excel)"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "sign.in"
filter(file.explode(attachments[])[].scan.strings.strings, strings.ilike(file.explode(attachments[])[], '*password*')) length_compare "2"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#69;&#110;&#116;&#101;&#114;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#70;&#111;&#114;&#103;&#111;&#116;&#116;&#101;&#110;&#32;&#109;&#121;&#32;&#112;&#97;&#115;&#115;&#119;&#111;&#114;&#100"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "&#83;&#105;&#103;&#110;&#32;&#105;&#110"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].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 in (new, outlier)"
or
and
headers.auth_summary.spf.pass eq "true"
macro "sender.email.domain.root_domain in org_domains"
macro "sender.email.domain.root_domain not in org_domains"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.auth_summary.spf.pass | eq |
| field:"headers.auth_summary.spf.pass" kind:eq value:"true" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML file contains exclusively Javascript
#Attached HTML file does not contain any HTML other than a <script> block.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
length(.scan.strings.strings) == 1
and any(.scan.strings.strings,
regex.imatch(., '\s{0,}<script.*')
)
and any(.scan.strings.strings,
strings.ends_with(., "</script>")
)
)
)
Detection logic
Scope: inbound message.
Attached HTML file does not contain any HTML other than a <script> block.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:- length(.scan.strings.strings) is 1
any of
.scan.strings.stringswhere:- . matches '\\s{0,}<script.*'
any of
.scan.strings.stringswhere:- . ends with '</script>'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.imatch, strings.ends_with. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.imatch | regex | \s{0,}<script.* |
strings.ends_with | suffix | </script> |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings ends_with "</script>"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "\\s{0,}<script.*"
file.explode(attachments[])[].scan.strings.strings length_compare "1"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML file with excessive 'const' declarations and abnormally long timeouts
#Detects messages with HTML attachments containing multiple 'const' declarations while excluding legitimate Gmail messages. This is evidence of potential code injection or obfuscation techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | HTML smuggling, Scripting, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
)
and strings.count(file.parse_html(.).raw, 'const') >= 7
and not regex.contains(file.parse_html(.).raw,
"<!-- saved from url=.{0,7}https://mail.google.com/mail/u/0/#inbox/"
)
and length(file.parse_html(.).raw) < 50000
// long timeouts
and regex.icontains(file.parse_html(.).raw,
'setTimeout\(\s*(?:function\s*)?\(.*?\)\s*(?:=>\s*)?\{[\s\S]*?\},\s*\d+\);',
// const delay = new Promise((resolve) => setTimeout(resolve, 100));
'setTimeout\(\s*\w+\,\s*\d{3,}\)+;'
)
)
// negate highly trusted sender domains unless they fail DMARC authentication or DMARC is missing
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 with HTML attachments containing multiple 'const' declarations while excluding legitimate Gmail messages. This is evidence of potential code injection or obfuscation techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
- strings.count(file.parse_html(.).raw, 'const') ≥ 7
not:
- file.parse_html(.).raw matches '<!-- saved from url=.{0,7}https://mail.google.com/mail/u/0/#inbox/'
- length(file.parse_html(.).raw) < 50000
file.parse_html(.).raw matches any of 2 patterns
setTimeout\(\s*(?:function\s*)?\(.*?\)\s*(?:=>\s*)?\{[\s\S]*?\},\s*\d+\);setTimeout\(\s*\w+\,\s*\d{3,}\)+;
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_html, regex.contains, regex.icontains, strings.count. Reference lists: $high_trust_sender_root_domains.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.icontains | regex | setTimeout\(\s*(?:function\s*)?\(.*?\)\s*(?:=>\s*)?\{[\s\S]*?\},\s*\d+\); |
regex.icontains | regex | setTimeout\(\s*\w+\,\s*\d{3,}\)+; |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
not
file.parse_html(attachments[]).raw regex_match "<!-- saved from url=.{0,7}https://mail.google.com/mail/u/0/#inbox/"
or
file.parse_html(attachments[]).raw regex_match "setTimeout\\(\\s*(?:function\\s*)?\\(.*?\\)\\s*(?:=>\\s*)?\\{[\\s\\S]*?\\},\\s*\\d+\\);"
file.parse_html(attachments[]).raw regex_match "setTimeout\\(\\s*\\w+\\,\\s*\\d{3,}\\)+;"
file.parse_html(attachments[]).raw length_compare "50000"
strings.count func_call "strings.count(file.parse_html(attachments[]).raw, \"const\") >= 7"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML file with excessive padding and suspicious patterns
#Attached HTML file contains excessive line breaks and suspicious Javascript patterns.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.content_type == "text/html"
or .file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.yara.matches, .name == "HTML_EXCESSIVE_PADDING")
)
)
Detection logic
Scope: inbound message.
Attached HTML file contains excessive line breaks and suspicious Javascript patterns.
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'text/html'
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'HTML_EXCESSIVE_PADDING'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | text/html |
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].scan.yara.matches[].name | equals | HTML_EXCESSIVE_PADDING |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.yara.matches)
file.explode(attachments).scan.yara.matches.name eq "HTML_EXCESSIVE_PADDING"
or
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML file with reference to recipient and suspicious patterns
#Attached HTML file (or HTML file within an attached email) contains references to the recipients email address, indicative of credential phishing, and suspicious Javascript patterns.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.content_type == "text/html"
or (.content_type == "message/rfc822" or .file_extension in ('eml'))
or .file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
)
and any(file.explode(.),
.flavors.mime in~ ("text/html", "text/plain")
and any(recipients.to,
any(..scan.strings.strings,
strings.icontains(., ..email.email)
)
and (
.email.domain.valid
or strings.icontains(.display_name, "undisclosed")
)
)
)
and any(file.explode(.),
(
any(.flavors.yara, . == "javascript_file")
// common indicator of HTML smuggling
and length(filter(.scan.javascript.identifiers,
strings.ilike(., "_0x*")
)
) > 50
)
or (
// javascript that doesn't get pulled out properly
.flavors.mime == "text/plain"
and strings.ilike(.file_name, "script*")
// common indicator of HTML smuggling
and length(filter(.scan.strings.strings,
regex.imatch(., ".*_0x.*")
)
) > 50
)
)
)
Detection logic
Scope: inbound message.
Attached HTML file (or HTML file within an attached email) contains references to the recipients email address, indicative of credential phishing, and suspicious Javascript patterns.
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'text/html'
any of:
- .content_type is 'message/rfc822'
- .file_extension in ('eml')
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
any of
file.explode(.)where all hold:- .flavors.mime in ('text/html', 'text/plain')
any of
recipients.towhere all hold:any of
.scan.strings.stringswhere:- strings.icontains(.)
any of:
- .email.domain.valid
- .display_name contains 'undisclosed'
any of
file.explode(.)where any holds:all of:
any of
.flavors.yarawhere:- . is 'javascript_file'
- length(filter(.scan.javascript.identifiers, strings.ilike(., '_0x*'))) > 50
all of:
- .flavors.mime is 'text/plain'
- .file_name matches 'script*'
- length(filter(.scan.strings.strings, regex.imatch(., '.*_0x.*'))) > 50
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, regex.imatch, strings.icontains, strings.ilike.
Indicators matched (16)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | text/html |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].flavors.mime | member | text/html |
file.explode(attachments[])[].flavors.mime | member | text/plain |
strings.icontains | substring | undisclosed |
file.explode(attachments[])[].flavors.yara[] | equals | javascript_file |
4 more
strings.ilike | substring | _0x* |
file.explode(attachments[])[].flavors.mime | equals | text/plain |
strings.ilike | substring | script* |
regex.imatch | regex | .*_0x.* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(recipients.to)
and
or
recipients.to.display_name contains "undisclosed"
recipients.to.email.domain.valid eq "true"
any(file.explode(attachments).scan.strings.strings)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.strings.strings[])"
file.explode(attachments[])[].flavors.mime in ["text/html", "text/plain"]
any(file.explode(attachments))
or
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "javascript_file"
filter(file.explode(attachments[])[].scan.javascript.identifiers, strings.ilike(file.explode(attachments[])[], '_0x*')) length_compare "50"
and
file.explode(attachments[])[].file_name starts_with "script"
file.explode(attachments[])[].flavors.mime eq "text/plain"
filter(file.explode(attachments[])[].scan.strings.strings, regex.imatch(file.explode(attachments[])[], '.*_0x.*')) length_compare "50"
or
attachments.content_type eq "message/rfc822"
attachments.content_type eq "text/html"
attachments.file_extension eq "eml"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling 'body onload' linking to suspicious destination
#Potential HTML Smuggling. This rule inspects HTML attachments that contain a single link and leveraging an HTML body onload event. The linked domain must be in the URLhaus trusted repoters list, or have a suspicious TLD.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "text/html"
)
and any(file.explode(.),
not length(.scan.url.invalid_urls) > 0
and length(.scan.url.urls) == 1
and any(.scan.strings.strings,
strings.ilike(., "*body onload*")
)
and (
any(.scan.url.urls,
.domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters
// To-do uncomment below when list is created
// or .domain.root_domain in $suspicious_root_domains
or .domain.tld in $suspicious_tlds
)
)
)
)
Detection logic
Scope: inbound message.
Potential HTML Smuggling. This rule inspects HTML attachments that contain a single link and leveraging an HTML body onload event. The linked domain must be in the URLhaus trusted repoters list, or have a suspicious TLD.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'xhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'text/html'
any of
file.explode(.)where all hold:not:
- length(.scan.url.invalid_urls) > 0
- length(.scan.url.urls) is 1
any of
.scan.strings.stringswhere:- . matches '*body onload*'
any of
.scan.url.urlswhere any holds:- .domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters
- .domain.tld in $suspicious_tlds
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $abuse_ch_urlhaus_domains_trusted_reporters, $file_extensions_common_archives, $suspicious_tlds.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | xhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
strings.ilike | substring | *body onload* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
or
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in abuse_ch_urlhaus_domains_trusted_reporters"
macro "file.explode(attachments[])[].scan.url.urls[].domain.tld in suspicious_tlds"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "body onload"
not
file.explode(attachments[])[].scan.url.invalid_urls length_compare "0"
file.explode(attachments[])[].scan.url.urls length_compare "1"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml", "xhtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling 'body onload' with high entropy and suspicious text
#Potential HTML Smuggling. This rule inspects HTML attachments that contain "body unload", high entropy, and suspicious text.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "text/html"
)
and any(file.explode(.),
.scan.entropy.entropy >= 5
and any(.scan.strings.strings,
strings.ilike(., "*body onload*")
)
and any(.scan.strings.strings,
regex.icontains(., 'data:image/.*;base64')
)
and any(.scan.strings.strings,
strings.ilike(., "*document pass*")
)
)
)
Detection logic
Scope: inbound message.
Potential HTML Smuggling. This rule inspects HTML attachments that contain "body unload", high entropy, and suspicious text.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'xhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'text/html'
any of
file.explode(.)where all hold:- .scan.entropy.entropy ≥ 5
any of
.scan.strings.stringswhere:- . matches '*body onload*'
any of
.scan.strings.stringswhere:- . matches 'data:image/.*;base64'
any of
.scan.strings.stringswhere:- . matches '*document pass*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | xhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
strings.ilike | substring | *body onload* |
regex.icontains | regex | data:image/.*;base64 |
strings.ilike | substring | *document pass* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "body onload"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "document pass"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "data:image/.*;base64"
file.explode(attachments[])[].scan.entropy.entropy ge "5"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml", "xhtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling - QR Code with suspicious links
#This rule detects messages with HTML attachments containing QR codes
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 1 <= length(attachments) < 3
// inspects HTML attachments for QR codes
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "text/html"
)
and any(file.explode(file.html_screenshot(.)),
// any URL
ml.link_analysis(.scan.qr.url).submitted
// currently we won't pick it up as a URL if it's
// not prefaced with a scheme. this is not very strong,
// but it's unlikely to cause FPs for this rule
or regex.contains(.scan.qr.data, '\.')
)
)
// 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.
This rule detects messages with HTML attachments containing QR codes
- inbound message
all of:
- length(attachments) ≥ 1
- length(attachments) < 3
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'xhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'text/html'
any of
file.explode(...)where any holds:- ml.link_analysis(.scan.qr.url).submitted
- .scan.qr.data matches '\\.'
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
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, file.html_screenshot, ml.link_analysis, profile.by_sender, regex.contains. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | xhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
regex.contains | regex | \. |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml", "xhtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
any(file.explode(...))
or
file.explode(...).scan.qr.data regex_match "\\."
ml.link_analysis func_call "ml.link_analysis(file.explode(...)[].scan.qr.url).submitted"
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"
attachments length_compare "1"
attachments length_compare "3"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling Microsoft sign in
#Scans HTML files to detect HTML smuggling techniques impersonating a Microsoft login page.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free subdomain host, HTML smuggling, Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
.scan.entropy.entropy >= 5.7
and .flavors.mime == "text/html"
and length(.scan.javascript.identifiers) == 0
and any(.scan.url.urls,
.domain.domain not in $tranco_1m
or .domain.root_domain in $free_subdomain_hosts
)
// seen in the wild: "sign in to your account", "sign in to your microsoft account"
and strings.ilike(.scan.html.title, "*sign in*", "*microsoft*")
)
)
// allow Microsoft domains just to be safe
and sender.email.domain.root_domain not in~ (
'microsoft.com',
'microsoftsupport.com',
'office.com'
)
Detection logic
Scope: inbound message.
Scans HTML files to detect HTML smuggling techniques impersonating a Microsoft login page.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:- .scan.entropy.entropy ≥ 5.7
- .flavors.mime is 'text/html'
- length(.scan.javascript.identifiers) is 0
any of
.scan.url.urlswhere any holds:- .domain.domain not in $tranco_1m
- .domain.root_domain in $free_subdomain_hosts
.scan.html.title matches any of 2 patterns
*sign in**microsoft*
- sender.email.domain.root_domain not in ('microsoft.com', 'microsoftsupport.com', 'office.com')
Inspects: attachments[].file_extension, attachments[].file_type, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives, $free_subdomain_hosts, $tranco_1m.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].flavors.mime | equals | text/html |
strings.ilike | substring | *sign in* |
strings.ilike | substring | *microsoft* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
or
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain not in tranco_1m"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
or
file.explode(attachments[])[].scan.html.title match "microsoft"
file.explode(attachments[])[].scan.html.title match "sign in"
file.explode(attachments[])[].flavors.mime eq "text/html"
file.explode(attachments[])[].scan.entropy.entropy ge "5.7"
file.explode(attachments[])[].scan.javascript.identifiers length_compare "0"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
not
sender.email.domain.root_domain in ["microsoft.com", "microsoftsupport.com", "office.com"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | in | microsoft.com, microsoftsupport.com, office.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"microsoft.com" field:"sender.email.domain.root_domain" value:"microsoftsupport.com" field:"sender.email.domain.root_domain" value:"office.com" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with atob and high entropy
#Recursively scans files and archives to detect HTML smuggling techniques using Javascript atob functions.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "eml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "message/rfc822"
or .file_extension in ('eml')
)
and any(file.explode(.),
.scan.entropy.entropy >= 5
and (
length(filter(.scan.javascript.identifiers,
strings.like(., "document", "write", "atob")
)
) == 3
// usage: document['write'](atob)
or any(.scan.strings.strings,
regex.icontains(., "document.{0,10}write.{0,10}atob")
)
// 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: {src: atob
or any(.scan.strings.strings,
strings.ilike(., "*{src: 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 : 'at'+'ob'
or any(.scan.strings.strings, strings.ilike(., "*'at'+'ob'*"))
// 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*")
)
)
)
)
// negate bouncebacks and undeliverables
and not any(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
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques using Javascript atob functions.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'eml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'message/rfc822'
- .file_extension in ('eml')
any of
file.explode(.)where all hold:- .scan.entropy.entropy ≥ 5
any of:
- length(filter(.scan.javascript.identifiers, strings.like(., 'document', 'write', 'atob'))) is 3
any of
.scan.strings.stringswhere:- . matches 'document.{0,10}write.{0,10}atob'
any of
.scan.strings.stringswhere:- . matches '=.?atob.*;'
any of
.scan.strings.stringswhere:- . matches '*atob?atob*'
any of
.scan.strings.stringswhere:- . matches '*{src: atob*'
any of
.scan.strings.stringswhere:- . matches '*eval?atob*'
any of
.scan.strings.stringswhere:- . matches '*atob(?0x*'
any of
.scan.strings.stringswhere:- . matches "*'at'+'ob'*"
any of
.scan.javascript.identifierswhere:- . matches '*ato\\u0062*'
any of
.scan.strings.stringswhere:- . matches '*document*insertAdjacentHTML*atob*'
not:
any of
attachmentswhere:- .content_type in ('message/global-delivery-status', 'message/delivery-status')
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, regex.icontains, strings.ilike, strings.like. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains.
Indicators matched (19)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | eml |
attachments[].file_type | equals | html |
attachments[].content_type | equals | message/rfc822 |
strings.like | substring | document |
strings.like | substring | write |
strings.like | substring | atob |
regex.icontains | regex | document.{0,10}write.{0,10}atob |
regex.icontains | regex | =.?atob.*; |
7 more
strings.ilike | substring | *atob?atob* |
strings.ilike | substring | *{src: atob* |
strings.ilike | substring | *eval?atob* |
strings.ilike | substring | *atob(?0x* |
strings.ilike | substring | *'at'+'ob'* |
strings.ilike | substring | *ato\u0062* |
strings.ilike | substring | *document*insertAdjacentHTML*atob* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers match "ato\\u0062"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "'at'+'ob'"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "atob(?0x"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "atob?atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "eval?atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "{src: atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "=.?atob.*;"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "document.{0,10}write.{0,10}atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*document*insertAdjacentHTML*atob*"
filter(file.explode(attachments[])[].scan.javascript.identifiers, strings.like(file.explode(attachments[])[], 'document', 'write', 'atob')) length_compare "3"
file.explode(attachments[])[].scan.entropy.entropy ge "5"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
attachments.file_extension in ["dhtml", "eml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].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"
not
any(attachments)
attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with atob and high entropy via calendar invite
#Scans calendar invites (.ics files) to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, ICS Phishing, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_extension =~ "ics" or .content_type == "text/calendar")
and any(file.explode(.),
.scan.entropy.entropy >= 5
and (
length(filter(.scan.javascript.identifiers,
strings.like(., "document", "write", "atob")
)
) == 3
// usage: document['write'](atob)
or any(.scan.strings.strings,
regex.icontains(., "document.{0,10}write.{0,10}atob")
)
// 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: {src: atob
or any(.scan.strings.strings,
strings.ilike(., "*{src: 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 : 'at'+'ob'
or any(.scan.strings.strings, strings.ilike(., "*'at'+'ob'*"))
// 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*")
)
)
)
)
// negate bouncebacks and undeliverables
and not any(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
)
Detection logic
Scope: inbound message.
Scans calendar invites (.ics files) to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'ics'
- .content_type is 'text/calendar'
any of
file.explode(.)where all hold:- .scan.entropy.entropy ≥ 5
any of:
- length(filter(.scan.javascript.identifiers, strings.like(., 'document', 'write', 'atob'))) is 3
any of
.scan.strings.stringswhere:- . matches 'document.{0,10}write.{0,10}atob'
any of
.scan.strings.stringswhere:- . matches '=.?atob.*;'
any of
.scan.strings.stringswhere:- . matches '*atob?atob*'
any of
.scan.strings.stringswhere:- . matches '*{src: atob*'
any of
.scan.strings.stringswhere:- . matches '*eval?atob*'
any of
.scan.strings.stringswhere:- . matches '*atob(?0x*'
any of
.scan.strings.stringswhere:- . matches "*'at'+'ob'*"
any of
.scan.javascript.identifierswhere:- . matches '*ato\\u0062*'
any of
.scan.strings.stringswhere:- . matches '*document*insertAdjacentHTML*atob*'
not:
any of
attachmentswhere:- .content_type in ('message/global-delivery-status', 'message/delivery-status')
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].content_type, attachments[].file_extension, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, regex.icontains, strings.ilike, strings.like. Reference lists: $high_trust_sender_root_domains.
Indicators matched (14)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
attachments[].content_type | equals | text/calendar |
strings.like | substring | document |
strings.like | substring | write |
strings.like | substring | atob |
regex.icontains | regex | document.{0,10}write.{0,10}atob |
regex.icontains | regex | =.?atob.*; |
strings.ilike | substring | *atob?atob* |
strings.ilike | substring | *{src: atob* |
strings.ilike | substring | *eval?atob* |
strings.ilike | substring | *atob(?0x* |
strings.ilike | substring | *'at'+'ob'* |
2 more
strings.ilike | substring | *ato\u0062* |
strings.ilike | substring | *document*insertAdjacentHTML*atob* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers match "ato\\u0062"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "'at'+'ob'"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "atob(?0x"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "atob?atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "eval?atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "{src: atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "=.?atob.*;"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "document.{0,10}write.{0,10}atob"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*document*insertAdjacentHTML*atob*"
filter(file.explode(attachments[])[].scan.javascript.identifiers, strings.like(file.explode(attachments[])[], 'document', 'write', 'atob')) length_compare "3"
file.explode(attachments[])[].scan.entropy.entropy ge "5"
or
attachments.content_type eq "text/calendar"
attachments.file_extension eq "ics"
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(attachments)
attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with auto-downloaded file
#HTML attachments containing files that are automatically downloaded with Javascript.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.javascript.identifiers, strings.ilike(., 'click'))
and any(.scan.javascript.identifiers,
strings.ilike(., 'addEventListener')
)
and (
length(filter(.scan.javascript.identifiers,
strings.like(., "document", "write", "atob")
)
) == 3
// usage: document['write'](atob)
or any(.scan.strings.strings,
strings.ilike(., "*document*write*atob*")
)
// usage: some_var = atob();
or any(.scan.strings.strings, strings.ilike(., "*=*atob*;"))
// 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*write*atob*",
"*document*insertAdjacentHTML*atob*"
)
)
)
)
)
Detection logic
Scope: inbound message.
HTML attachments containing files that are automatically downloaded with Javascript.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:any of
.scan.javascript.identifierswhere:- . matches 'click'
any of
.scan.javascript.identifierswhere:- . matches 'addEventListener'
any of:
- length(filter(.scan.javascript.identifiers, strings.like(., 'document', 'write', 'atob'))) is 3
any of
.scan.strings.stringswhere:- . matches '*document*write*atob*'
any of
.scan.strings.stringswhere:- . matches '*=*atob*;'
any of
.scan.javascript.identifierswhere:- . matches '*ato\\u0062*'
any of
.scan.strings.stringswhere:. matches any of 2 patterns
*document*write*atob**document*insertAdjacentHTML*atob*
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike, strings.like. Reference lists: $file_extensions_common_archives.
Indicators matched (14)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
strings.ilike | substring | click |
strings.ilike | substring | addEventListener |
strings.like | substring | document |
strings.like | substring | write |
strings.like | substring | atob |
strings.ilike | substring | *document*write*atob* |
strings.ilike | substring | *=*atob*; |
2 more
strings.ilike | substring | *ato\u0062* |
strings.ilike | substring | *document*insertAdjacentHTML*atob* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] wildcard "*document*insertAdjacentHTML*atob*"
file.explode(attachments[])[].scan.strings.strings[] wildcard "*document*write*atob*"
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers match "ato\\u0062"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*=*atob*;"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings wildcard "*document*write*atob*"
filter(file.explode(attachments[])[].scan.javascript.identifiers, strings.like(file.explode(attachments[])[], 'document', 'write', 'atob')) length_compare "3"
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers eq "addEventListener"
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers eq "click"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with base64 encoded JavaScript function
#This rule identifies attachments that either have an HTML extension, lack any file extension, or possess an unrecognized file type and are employing Base64 encoding to conceal JavaScript functions within HTML script tags with little to no other content. Such obfuscation tactics have been frequently observed in credential phishing campaigns.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
strings.contains(., "data:text/javascript;base64")
)
// strings array is small
and length(.scan.strings.strings) < 10
)
)
Detection logic
Scope: inbound message.
This rule identifies attachments that either have an HTML extension, lack any file extension, or possess an unrecognized file type and are employing Base64 encoding to conceal JavaScript functions within HTML script tags with little to no other content. Such obfuscation tactics have been frequently observed in credential phishing campaigns.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . contains 'data:text/javascript;base64'
- length(.scan.strings.strings) < 10
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.contains. Reference lists: $file_extensions_common_archives.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
strings.contains | substring | data:text/javascript;base64 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "data:text/javascript;base64"
file.explode(attachments[])[].scan.strings.strings length_compare "10"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with base64 encoded ZIP file
#Detects HTML attachments containing base64-encoded ZIP or Office files alongside JavaScript decoding functions such as atob, fromCharCode, or base64. This technique is commonly used to evade security controls by hiding malicious files within HTML content that are decoded and executed client-side.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
)
and (
// javascript functions to decode the base64
strings.icontains(file.parse_text(.).text, 'atob')
or strings.icontains(file.parse_text(.).text, 'fromCharCode')
or strings.icontains(file.parse_text(.).text, 'base64')
)
// Magic bytes for a ZIP/Office File that have been base64 encoded
and regex.contains(file.parse_text(.).text,
'[\x2C\x3B\x3A\x22\x27\x28\x7B\x5B\s]UEsDB'
)
// negation of Micro Focus Voltage Secure Messaging
and not strings.contains(file.parse_text(.).text,
"<input type=\"hidden\" name=\"ZFRdata\" value=\"\n-----BEGIN VOLTAGE SECURE BLOCK V3-----\nUEsDBBQAAAAAAAAAAA"
)
)
Detection logic
Scope: inbound message.
Detects HTML attachments containing base64-encoded ZIP or Office files alongside JavaScript decoding functions such as atob, fromCharCode, or base64. This technique is commonly used to evade security controls by hiding malicious files within HTML content that are decoded and executed client-side.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
any of:
- file.parse_text(.).text contains 'atob'
- file.parse_text(.).text contains 'fromCharCode'
- file.parse_text(.).text contains 'base64'
- file.parse_text(.).text matches '[\\x2C\\x3B\\x3A\\x22\\x27\\x28\\x7B\\x5B\\s]UEsDB'
not:
- file.parse_text(.).text contains '<input type=\\"hidden\\" name=\\"ZFRdata\\" value=\\"\\n-----BEGIN VOLTAGE SECURE BLOCK V3-----\\nUEsDBBQAAAAAAAAAAA'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.parse_text, regex.contains, strings.contains, strings.icontains.
Indicators matched (9)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
strings.icontains | substring | atob |
strings.icontains | substring | fromCharCode |
strings.icontains | substring | base64 |
regex.contains | regex | [\x2C\x3B\x3A\x22\x27\x28\x7B\x5B\s]UEsDB |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
not
file.parse_text(attachments[]).text contains "<input type=\\\"hidden\\\" name=\\\"ZFRdata\\\" value=\\\"\\n-----BEGIN VOLTAGE SECURE BLOCK V3-----\\nUEsDBBQAAAAAAAAAAA"
or
file.parse_text(attachments[]).text contains "atob"
file.parse_text(attachments[]).text contains "base64"
file.parse_text(attachments[]).text contains "fromCharCode"
file.parse_text(attachments[]).text regex_match "[\\x2C\\x3B\\x3A\\x22\\x27\\x28\\x7B\\x5B\\s]UEsDB"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with concatenation obfuscation
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(.,
"*CJzYyIuY29uY2F0KCJyaXB0Iik*",
'*"sc".concat("ript")*'
)
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:. matches any of 2 patterns
*CJzYyIuY29uY2F0KCJyaXB0Iik**"sc".concat("ript")*
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
strings.ilike | substring | *CJzYyIuY29uY2F0KCJyaXB0Iik* |
strings.ilike | substring | *"sc".concat("ript")* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "CJzYyIuY29uY2F0KCJyaXB0Iik"
file.explode(attachments[])[].scan.strings.strings[] match "\"sc\".concat(\"ript\")"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with decimal encoding
#Potential HTML smuggling attack based on large blocks of decimal encoding. Attackers often use decimal encoding as an obfuscation technique to bypass traditional email security measures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "text/html"
)
and any(file.explode(.),
// suspicious identifiers
any(.scan.strings.strings, regex.contains(., '(\d{2,3},){60,}'))
)
)
// 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.
Potential HTML smuggling attack based on large blocks of decimal encoding. Attackers often use decimal encoding as an obfuscation technique to bypass traditional email security measures.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'xhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'text/html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '(\\d{2,3},){60,}'
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
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, profile.by_sender, regex.contains. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | xhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
regex.contains | regex | (\d{2,3},){60,} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml", "xhtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "(\\d{2,3},){60,}"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with embedded base64 streamed file download
#HTML attachments containing base64-encoded files that are downloaded via embedded hyperlinks. This TTP is used by attackers to bypass email and web filters since the file is not downloaded from an external source. Recently observed delivering Qakbot.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | HTML smuggling, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
regex.icontains(.,
'<a href="data:application/octet-stream;base64,[a-z0-9/+]+={0,2}" download=".+\.[a-z]{2,3}'
)
)
)
)
Detection logic
Scope: inbound message.
HTML attachments containing base64-encoded files that are downloaded via embedded hyperlinks. This TTP is used by attackers to bypass email and web filters since the file is not downloaded from an external source. Recently observed delivering Qakbot.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '<a href="data:application/octet-stream;base64,[a-z0-9/+]+={0,2}" download=".+\\.[a-z]{2,3}'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.icontains | regex | <a href="data:application/octet-stream;base64,[a-z0-9/+]+={0,2}" download=".+\.[a-z]{2,3} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "<a href=\"data:application/octet-stream;base64,[a-z0-9/+]+={0,2}\" download=\".+\\.[a-z]{2,3}"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with embedded base64-encoded executable
#HTML attachmemt contains a base-64 encoded executable.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .flavors.mime == "text/plain"
)
and any(.flavors.yara, . == 'base64_pe')
)
)
Detection logic
Scope: inbound message.
HTML attachmemt contains a base-64 encoded executable.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .flavors.mime is 'text/plain'
any of
.flavors.yarawhere:- . is 'base64_pe'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (11)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].file_extension | member | html |
file.explode(attachments[])[].file_extension | member | htm |
file.explode(attachments[])[].file_extension | member | shtml |
file.explode(attachments[])[].file_extension | member | dhtml |
file.explode(attachments[])[].flavors.mime | equals | text/plain |
file.explode(attachments[])[].flavors.yara[] | equals | base64_pe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "base64_pe"
or
file.explode(attachments[])[].file_extension in ["dhtml", "htm", "html", "shtml"]
file.explode(attachments[])[].flavors.mime eq "text/plain"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with embedded base64-encoded ISO
#HTML attachment contains a base-64 encoded ISO. This is a known TTP for multiple threat actors.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, ISO |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(.,
// Base64 encoded ISOs
"*SVNPIDk2NjAvSEZT*",
"*MTk5MyBFLllPVU5HREFMRQ*",
// Reversed base64 encoded ISOs
"*TZESvAjN2kDIPNVS*",
"*QRMFERH5UVPllLFByM5kTM*"
)
)
)
)
Detection logic
Scope: inbound message.
HTML attachment contains a base-64 encoded ISO. This is a known TTP for multiple threat actors.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:. matches any of 4 patterns
*SVNPIDk2NjAvSEZT**MTk5MyBFLllPVU5HREFMRQ**TZESvAjN2kDIPNVS**QRMFERH5UVPllLFByM5kTM*
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_type | equals | html |
strings.ilike | substring | *SVNPIDk2NjAvSEZT* |
strings.ilike | substring | *MTk5MyBFLllPVU5HREFMRQ* |
strings.ilike | substring | *TZESvAjN2kDIPNVS* |
strings.ilike | substring | *QRMFERH5UVPllLFByM5kTM* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "MTk5MyBFLllPVU5HREFMRQ"
file.explode(attachments[])[].scan.strings.strings[] match "QRMFERH5UVPllLFByM5kTM"
file.explode(attachments[])[].scan.strings.strings[] match "SVNPIDk2NjAvSEZT"
file.explode(attachments[])[].scan.strings.strings[] match "TZESvAjN2kDIPNVS"
or
attachments.file_extension in ["htm", "html"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with eval and atob
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
// usage: onerror="eval(atob('
any(.scan.strings.strings,
regex.imatch(., ".*eval.{1,4}atob.*")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '.*eval.{1,4}atob.*'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.imatch. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.imatch | regex | .*eval.{1,4}atob.* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match ".*eval.{1,4}atob.*"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with eval and atob via calendar invite
#Scans calendar invites (.ics files) to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, ICS Phishing, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_extension =~ "ics" or .content_type == "text/calendar")
// usage: onerror="eval(atob('
and regex.imatch(file.parse_text(.).text, ".*eval.{1,4}atob.*")
)
Detection logic
Scope: inbound message.
Scans calendar invites (.ics files) to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'ics'
- .content_type is 'text/calendar'
- file.parse_text(.).text matches '.*eval.{1,4}atob.*'
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.parse_text, regex.imatch.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
attachments[].content_type | equals | text/calendar |
regex.imatch | regex | .*eval.{1,4}atob.* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type eq "text/calendar"
attachments.file_extension eq "ics"
file.parse_text(attachments[]).text regex_match ".*eval.{1,4}atob.*"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with excessive line break obfuscation
#Credential Phishing attacks have been observed using excessive line breaks to obfuscate javascript functions within html files.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
// return new line padded obfuscation
regex.contains(., '(\\r\\n\S{2}){50,}')
and strings.contains(., 'decodeURIComponent')
)
)
)
Detection logic
Scope: inbound message.
Credential Phishing attacks have been observed using excessive line breaks to obfuscate javascript functions within html files.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere all hold:- . matches '(\\\\r\\\\n\\S{2}){50,}'
- . contains 'decodeURIComponent'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.contains, strings.contains. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.contains | regex | (\\r\\n\S{2}){50,} |
strings.contains | substring | decodeURIComponent |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
and
file.explode(attachments[])[].scan.strings.strings[] contains "decodeURIComponent"
file.explode(attachments[])[].scan.strings.strings[] regex_match "(\\\\r\\\\n\\S{2}){50,}"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with excessive string concatenation and suspicious patterns
#Attached HTML file contains excessive string concatenation, a recipient's email address, and an indicator of HTML smuggling. This pattern has been seen in the wild in an attempt to obfuscate the file's contents.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
// HTML file, or something like it
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
or .file_type == "html"
)
// small HTML file
and .size < 5000
// lots of concatenation (obfuscation technique)
and strings.count(file.parse_html(.).raw, "+") > 20
// contains a recipient's email address
and any(recipients.to,
strings.icontains(file.parse_html(..).raw, .email.email)
and .email.domain.valid
)
// HTML smuggling
and 1 of (
strings.ilike(file.parse_html(.).raw, "*window.location.href*"),
strings.ilike(file.parse_html(.).raw, "*createObjectURL*")
)
)
Detection logic
Scope: inbound message.
Attached HTML file contains excessive string concatenation, a recipient's email address, and an indicator of HTML smuggling. This pattern has been seen in the wild in an attempt to obfuscate the file's contents.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- .file_type is 'html'
- .size < 5000
- strings.count(file.parse_html(.).raw, '+') > 20
any of
recipients.towhere all hold:- strings.icontains(file.parse_html(.).raw)
- .email.domain.valid
at least 1 of:
- file.parse_html(.).raw matches '*window.location.href*'
- file.parse_html(.).raw matches '*createObjectURL*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.parse_html, strings.count, strings.icontains, strings.ilike.
Indicators matched (9)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
strings.ilike | substring | *window.location.href* |
strings.ilike | substring | *createObjectURL* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
any(recipients.to)
and
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(file.parse_html(attachments[]).raw)"
or
file.parse_html(attachments[]).raw match "createObjectURL"
file.parse_html(attachments[]).raw match "window.location.href"
attachments.size lt "5000"
strings.count func_call "strings.count(file.parse_html(attachments[]).raw, \"+\") > 20"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with fromCharCode and other signals
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
length(.scan.javascript.identifiers) < 100
and "location" in .scan.javascript.identifiers
and "charCodeAt" in .scan.javascript.identifiers
and "fromCharCode" in .scan.javascript.identifiers
and "indexOf" in .scan.javascript.identifiers
and "try" in .scan.javascript.keywords
and "catch" in .scan.javascript.keywords
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:- length(.scan.javascript.identifiers) < 100
- .scan.javascript.identifiers contains 'location'
- .scan.javascript.identifiers contains 'charCodeAt'
- .scan.javascript.identifiers contains 'fromCharCode'
- .scan.javascript.identifiers contains 'indexOf'
- .scan.javascript.keywords contains 'try'
- .scan.javascript.keywords contains 'catch'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (11)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].scan.javascript.identifiers | contains | location |
file.explode(attachments[])[].scan.javascript.identifiers | contains | charCodeAt |
file.explode(attachments[])[].scan.javascript.identifiers | contains | fromCharCode |
file.explode(attachments[])[].scan.javascript.identifiers | contains | indexOf |
file.explode(attachments[])[].scan.javascript.keywords | contains | try |
file.explode(attachments[])[].scan.javascript.keywords | contains | catch |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.javascript.identifiers contains "charCodeAt"
file.explode(attachments[])[].scan.javascript.identifiers contains "fromCharCode"
file.explode(attachments[])[].scan.javascript.identifiers contains "indexOf"
file.explode(attachments[])[].scan.javascript.identifiers contains "location"
file.explode(attachments[])[].scan.javascript.identifiers length_compare "100"
file.explode(attachments[])[].scan.javascript.keywords contains "catch"
file.explode(attachments[])[].scan.javascript.keywords contains "try"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with hex strings
#Recursively scans files and archives to detect HTML smuggling using hex-encoded string content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
// ["\x00\x00\x00\xAA..."]
regex.icontains(., '(\\x([a-zA-Z0-9]{2})){100}')
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling using hex-encoded string content.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '(\\\\x([a-zA-Z0-9]{2})){100}'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.icontains | regex | (\\x([a-zA-Z0-9]{2})){100} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "(\\\\x([a-zA-Z0-9]{2})){100}"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with high entropy and other signals
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
.scan.entropy.entropy >= 5
and any(.scan.strings.strings,
regex.icontains(., "fromCharCode")
and regex.icontains(., "parseInt")
and regex.icontains(., "charCodeAt")
and regex.icontains(., '(\\x0.*?){50}')
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:- .scan.entropy.entropy ≥ 5
any of
.scan.strings.stringswhere all hold:- . matches 'fromCharCode'
- . matches 'parseInt'
- . matches 'charCodeAt'
- . matches '(\\\\x0.*?){50}'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (9)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.icontains | regex | fromCharCode |
regex.icontains | regex | parseInt |
regex.icontains | regex | charCodeAt |
regex.icontains | regex | (\\x0.*?){50} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
and
file.explode(attachments[])[].scan.strings.strings[] regex_match "(\\\\x0.*?){50}"
file.explode(attachments[])[].scan.strings.strings[] regex_match "charCodeAt"
file.explode(attachments[])[].scan.strings.strings[] regex_match "fromCharCode"
file.explode(attachments[])[].scan.strings.strings[] regex_match "parseInt"
file.explode(attachments[])[].scan.entropy.entropy ge "5"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with raw array buffer
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, Free subdomain host, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
// arrayBuffer, eg repetition:
// [0xa0,0x8e,0xd0,0x60,...]
regex.icontains(., '(\W?0x[a-zA-Z0-9]{2}\W?,\s*){100}')
)
and any(.scan.strings.strings, strings.contains(., ".map"))
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . matches '(\\W?0x[a-zA-Z0-9]{2}\\W?,\\s*){100}'
any of
.scan.strings.stringswhere:- . contains '.map'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.icontains, strings.contains. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
regex.icontains | regex | (\W?0x[a-zA-Z0-9]{2}\W?,\s*){100} |
strings.contains | substring | .map |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains ".map"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "(\\W?0x[a-zA-Z0-9]{2}\\W?,\\s*){100}"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with RC4 decryption
#Potential HTML smuggling. The RC4 algorithm is used within inline JavaScript to decrypt the payload on-the-fly.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(., "*?[(?[?]+?[?])%256]*")
)
)
)
Detection logic
Scope: inbound message.
Potential HTML smuggling. The RC4 algorithm is used within inline JavaScript to decrypt the payload on-the-fly.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '*?[(?[?]+?[?])%256]*'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
strings.ilike | substring | *?[(?[?]+?[?])%256]* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "?[(?[?]+?[?])%256]"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with ROT13
#Potential HTML obfuscation attack based on suspicious JavaScript identifiers. Some attackers may use obfuscation techniques such as ROT13 to bypass email security filters. This rule may be expanded to inspect HTML attachments for other suspicious identifiers.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Encryption, Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type in~ ("html", "svg")
)
and any(file.explode(.),
1 of (
any(.scan.javascript.identifiers,
. in~ ("rot13", "decodeROT13")
),
any(.scan.strings.strings,
// ROT13 encoded value for https & http
strings.icontains(., "\"uggcf://")
or strings.icontains(., "\"uggc://")
)
)
and length(.scan.javascript.identifiers) < 100
)
)
Detection logic
Scope: inbound message.
Potential HTML obfuscation attack based on suspicious JavaScript identifiers. Some attackers may use obfuscation techniques such as ROT13 to bypass email security filters. This rule may be expanded to inspect HTML attachments for other suspicious identifiers.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type in ('html', 'svg')
any of
file.explode(.)where all hold:at least 1 of:
any of
.scan.javascript.identifierswhere:- . in ('rot13', 'decodeROT13')
any of
.scan.strings.stringswhere any holds:- . contains '\\"uggcf://'
- . contains '\\"uggc://'
- length(.scan.javascript.identifiers) < 100
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.icontains. Reference lists: $file_extensions_common_archives.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | member | html |
attachments[].file_type | member | svg |
file.explode(attachments[])[].scan.javascript.identifiers[] | member | rot13 |
file.explode(attachments[])[].scan.javascript.identifiers[] | member | decodeROT13 |
strings.icontains | substring | \"uggcf:// |
strings.icontains | substring | \"uggc:// |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] contains "\\\"uggc://"
file.explode(attachments[])[].scan.strings.strings[] contains "\\\"uggcf://"
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers in ["decodeROT13", "rot13"]
file.explode(attachments[])[].scan.javascript.identifiers length_compare "100"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type in ["html", "svg"]
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with setTimeout
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.size <= 400
and (
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
"setTimeout" in .scan.javascript.identifiers
and any(.scan.strings.strings,
strings.ilike(., "*location.href*")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:- .size ≤ 400
any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where all hold:- .scan.javascript.identifiers contains 'setTimeout'
any of
.scan.strings.stringswhere:- . matches '*location.href*'
Inspects: attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].scan.javascript.identifiers | contains | setTimeout |
strings.ilike | substring | *location.href* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "location.href"
file.explode(attachments[])[].scan.javascript.identifiers contains "setTimeout"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.size le "400"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML smuggling with unescape
#Recursively scans files and archives to detect HTML smuggling techniques.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
)
and any(file.explode(.),
any(.scan.javascript.identifiers, . == "unescape")
or any(.scan.strings.strings,
regex.contains(., "document.write.{0,10}unescape")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect HTML smuggling techniques.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
any of
file.explode(.)where any holds:any of
.scan.javascript.identifierswhere:- . is 'unescape'
any of
.scan.strings.stringswhere:- . matches 'document.write.{0,10}unescape'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, regex.contains. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
file.explode(attachments[])[].scan.javascript.identifiers[] | equals | unescape |
regex.contains | regex | document.write.{0,10}unescape |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.javascript.identifiers)
file.explode(attachments).scan.javascript.identifiers eq "unescape"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "document.write.{0,10}unescape"
or
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML with emoji-to-character map
#Detects inbound messages containing HTML attachments with an unusually high number of emojis in a list, sent from untrusted or suspicious senders who lack an established sending history or have previous malicious behavior.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling, Impersonation: Brand, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .file_type == "html"
or .content_type in ("application/octet-stream", "text/html")
)
and regex.icount(file.parse_html(.).raw,
'[\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}].{0,10},'
) > 10
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
Detection logic
Scope: inbound message.
Detects inbound messages containing HTML attachments with an unusually high number of emojis in a list, sent from untrusted or suspicious senders who lack an established sending history or have previous malicious behavior.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
- .content_type in ('application/octet-stream', 'text/html')
- regex.icount(file.parse_html(.).raw, '[\\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}].{0,10},') > 10
any of:
all of:
- profile.by_sender().prevalence in ('new', 'outlier')
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_html, profile.by_sender, regex.icount. Reference lists: $high_trust_sender_root_domains.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_type | equals | html |
attachments[].content_type | member | application/octet-stream |
attachments[].content_type | member | text/html |
regex.icount | regex | [\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}].{0,10}, |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type in ["application/octet-stream", "text/html"]
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
regex.icount func_call "regex.icount(file.parse_html(attachments[]).raw, \"[\\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}].{0,10},\") > 10"
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().solicited"
profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML with JavaScript functions for HTTP requests
#This rule identifies HTML attachments which contain multiple references to JavaScript functions that support making HTTP requests. This has been observed in phishing campaigns to load remote payloads into otherwise benign HTML attachments.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
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(attachments,
.file_extension in~ ("html", "htm", "shtml", "dhtml")
and 3 of (
strings.icontains(file.parse_html(.).raw, '.replace'),
strings.icontains(file.parse_html(.).raw, 'XMLHttpRequest'),
strings.icontains(file.parse_html(.).raw, 'onreadystate'),
strings.icontains(file.parse_html(.).raw, 'GET'),
strings.icontains(file.parse_html(.).raw, 'send()'),
strings.icontains(file.parse_html(.).raw, 'responseText'),
)
)
Detection logic
Scope: inbound message.
This rule identifies HTML attachments which contain multiple references to JavaScript functions that support making HTTP requests. This has been observed in phishing campaigns to load remote payloads into otherwise benign HTML attachments.
- inbound message
not:
- profile.by_sender().solicited
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
any of
attachmentswhere all hold:- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
at least 3 of 6: file.parse_html(.).raw contains any of 6 patterns
.replaceXMLHttpRequestonreadystateGETsend()responseText
Inspects: attachments[].file_extension, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_html, profile.by_sender, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
strings.icontains | substring | .replace |
strings.icontains | substring | XMLHttpRequest |
strings.icontains | substring | onreadystate |
strings.icontains | substring | GET |
strings.icontains | substring | send() |
strings.icontains | substring | responseText |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
file.parse_html(attachments[]).raw contains ".replace"
file.parse_html(attachments[]).raw contains "GET"
file.parse_html(attachments[]).raw contains "XMLHttpRequest"
file.parse_html(attachments[]).raw contains "onreadystate"
file.parse_html(attachments[]).raw contains "responseText"
file.parse_html(attachments[]).raw contains "send()"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
not
profile.by_sender func_call "profile.by_sender().solicited"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: HTML with obfuscation and recipient's email in JavaScript strings
#Attached HTML file contains JavaScript code with suspicious identifiers like 'atob' or 'decrypt', as well as the recipient's email address embedded within the JavaScript
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml")
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
)
or .file_extension in~ $file_extensions_common_archives
or .file_type == "html"
or .content_type == "text/html"
)
and .size < 1000000
and any(file.explode(.),
// suspicious identifiers
any([.scan.strings.strings, .scan.javascript.identifiers],
any(., strings.like(., "*atob*", "*decrypt*"))
)
)
// Recipients address found in javascript
and any(file.explode(.),
(
any(recipients.to,
(
any(..scan.javascript.strings,
strings.icontains(., ..email.email)
)
or any(..scan.strings.strings,
strings.icontains(., ..email.email)
)
)
and (
.email.domain.valid
or strings.icontains(.display_name, "undisclosed")
)
)
)
)
// Negating Cisco Secure Email Encryption
and not any(file.explode(.),
any(.scan.javascript.strings,
strings.contains(., "Cisco Registered Envelope Service")
or strings.contains(., "https://res.cisco.com:443")
)
)
// Negating SolarWinds Kiwi Syslog server email reports
and not any(file.explode(.),
length(.scan.url.urls) > 0
and all(.scan.url.urls,
strings.contains(.domain.root_domain,
"kiwisyslog.com"
)
)
)
)
Detection logic
Scope: inbound message.
Attached HTML file contains JavaScript code with suspicious identifiers like 'atob' or 'decrypt', as well as the recipient's email address embedded within the JavaScript
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml', 'xhtml')
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .file_extension in $file_extensions_common_archives
- .file_type is 'html'
- .content_type is 'text/html'
- .size < 1000000
any of
file.explode(.)where:any of
[.scan.strings.strings, .scan.javascript.identifiers]where:any of
.where:. matches any of 2 patterns
*atob**decrypt*
any of
file.explode(.)where:any of
recipients.towhere all hold:any of:
any of
.scan.javascript.stringswhere:- strings.icontains(.)
any of
.scan.strings.stringswhere:- strings.icontains(.)
any of:
- .email.domain.valid
- .display_name contains 'undisclosed'
not:
any of
file.explode(.)where:any of
.scan.javascript.stringswhere any holds:- . contains 'Cisco Registered Envelope Service'
- . contains 'https://res.cisco.com:443'
not:
any of
file.explode(.)where all hold:- length(.scan.url.urls) > 0
all of
.scan.url.urlswhere:- .domain.root_domain contains 'kiwisyslog.com'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, strings.contains, strings.icontains, strings.like. Reference lists: $file_extensions_common_archives.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].file_extension | member | xhtml |
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
strings.like | substring | *atob* |
strings.like | substring | *decrypt* |
strings.icontains | substring | undisclosed |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(recipients.to)
and
or
any(file.explode(attachments).scan.javascript.strings)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.javascript.strings[])"
any(file.explode(attachments).scan.strings.strings)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.strings.strings[])"
or
recipients.to.display_name contains "undisclosed"
recipients.to.email.domain.valid eq "true"
any(file.explode(attachments))
any([file.explode(attachments).scan.strings.strings, file.explode(attachments).scan.javascript.identifiers])
any([file.explode(attachments).scan.strings.strings, file.explode(attachments).scan.javascript.identifiers])
or
[file.explode(attachments[])[].scan.strings.strings, file.explode(attachments[])[].scan.javascript.identifiers][][] match "atob"
[file.explode(attachments[])[].scan.strings.strings, file.explode(attachments[])[].scan.javascript.identifiers][][] match "decrypt"
not
any(file.explode(attachments))
any(file.explode(attachments).scan.javascript.strings)
or
file.explode(attachments[])[].scan.javascript.strings[] contains "Cisco Registered Envelope Service"
file.explode(attachments[])[].scan.javascript.strings[] contains "https://res.cisco.com:443"
not
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.url.urls length_compare "0"
macro "all(file.explode(attachments[])[].scan.url.urls)"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.content_type eq "text/html"
attachments.file_extension in ["dhtml", "htm", "html", "shtml", "xhtml"]
attachments.file_type eq "html"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.size lt "1000000"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar file with base64 encoded recipient address in URL parameters
#Detects inbound messages containing ICS calendar attachments where event links have multiple URL parameters, and the base64 decoded combination of those parameters matches the recipient's email address. This technique may be used to personalize malicious links or track specific targets.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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(filter(.links, length(.href_url.query_params_decoded) > 1),
any(strings.scan_base64(strings.concat(coalesce(flatten(values(.display_url.query_params_decoded
)
)[0],
""
),
coalesce(flatten(values(.display_url.query_params_decoded
)
)[1],
""
),
coalesce(flatten(values(.display_url.query_params_decoded
)
)[2],
""
),
coalesce(flatten(values(.display_url.query_params_decoded
)
)[3],
""
),
coalesce(flatten(values(.display_url.query_params_decoded
)
)[4],
""
),
coalesce(flatten(values(.display_url.query_params_decoded
)
)[5],
""
)
)
),
. == recipients.to[0].email.email
)
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing ICS calendar attachments where event links have multiple URL parameters, and the base64 decoded combination of those parameters matches the recipient's email address. This technique may be used to personalize malicious links or track specific targets.
- inbound message
any of
attachmentswhere 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(.).eventswhere:any of
filter(.links)where:any of
strings.scan_base64(...)where:- . is recipients.to[0].email.email
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, recipients.to[0].email.email, type.inbound. Sensors: beta.file.parse_ics, strings.concat, strings.scan_base64.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.file.parse_ics(attachments).events)
any(filter(beta.file.parse_ics(attachments).events.links))
any(strings.scan_base64(...))
strings.scan_base64(...) cross_field_compare "recipients.to[0].email.email"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar file with QR code containing recipient email address
#Detects calendar attachments (.ics files) containing QR codes that include the recipient's email address in the URL, URL fragment, or base64-encoded data. This technique is commonly used to personalize credential theft attacks by embedding the target's email address within calendar invitations.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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,
//
// 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(beta.scan_qr(file.html_screenshot(.description_html)).items,
strings.icontains(.url.url, recipients.to[0].email.email)
or any(strings.scan_base64(.url.url, format="url"),
strings.icontains(., recipients.to[0].email.email)
)
or any(strings.scan_base64(.url.fragment),
strings.icontains(., recipients.to[0].email.email)
)
)
)
)
Detection logic
Scope: inbound message.
Detects calendar attachments (.ics files) containing QR codes that include the recipient's email address in the URL, URL fragment, or base64-encoded data. This technique is commonly used to personalize credential theft attacks by embedding the target's email address within calendar invitations.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'ics'
any of:
- .file_extension is 'ics'
- .content_type in ('application/ics', 'text/calendar')
any of
beta.file.parse_ics(.).eventswhere:any of
beta.scan_qr(file.html_screenshot(.description_html)).itemswhere any holds:- strings.icontains(.url.url)
any of
strings.scan_base64(.url.url)where:- strings.icontains(.)
any of
strings.scan_base64(.url.fragment)where:- strings.icontains(.)
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, recipients.to[0].email.email, type.inbound. Sensors: beta.file.parse_ics, beta.scan_qr, file.html_screenshot, strings.icontains, strings.scan_base64.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.file.parse_ics(attachments).events)
any(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments).events.description_html)).items)
or
any(strings.scan_base64(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments).events.description_html)).items.url.fragment))
strings.icontains func_call "strings.icontains(strings.scan_base64(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments[]).events[].description_html)).items[].url.fragment)[])"
any(strings.scan_base64(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments).events.description_html)).items.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments[]).events[].description_html)).items[].url.url)[])"
strings.icontains func_call "strings.icontains(beta.scan_qr(file.html_screenshot(beta.file.parse_ics(attachments[]).events[].description_html)).items[].url.url)"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar file with recipient address in UID field
#Detects inbound messages containing ICS calendar attachments where the UID property matches the recipient's email address, indicating potential calendar-based social engineering.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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(.raw_properties,
.key == "UID" and .value == recipients.to[0].email.email
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing ICS calendar attachments where the UID property matches the recipient's email address, indicating potential calendar-based social engineering.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'ics'
any of:
- .file_extension is 'ics'
- .content_type in ('application/ics', 'text/calendar')
any of
beta.file.parse_ics(.).eventswhere:any of
.raw_propertieswhere all hold:- .key is 'UID'
- .value is recipients.to[0].email.email
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, recipients.to[0].email.email, type.inbound. Sensors: beta.file.parse_ics.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
beta.file.parse_ics(attachments[]).events[].raw_properties[].key | equals | UID |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.file.parse_ics(attachments).events)
any(beta.file.parse_ics(attachments).events.raw_properties)
and
beta.file.parse_ics(attachments[]).events[].raw_properties[].key eq "UID"
beta.file.parse_ics(attachments[]).events[].raw_properties[].value cross_field_compare "recipients.to[0].email.email"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar file with suspicious product identifier
#Detects inbound messages containing ICS calendar attachments that have product identifiers matching patterns commonly associated with malicious calendar invitations. The rule identifies ICS files through multiple detection methods and analyzes the product_id field for suspicious formatting that may indicate automated generation or spoofing attempts.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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 (
regex.icontains(beta.file.parse_ics(.).product_id,
'-//[a-z0-9]*[0-9][a-z0-9]*//EN'
)
or strings.icontains(beta.file.parse_ics(.).product_id,
"-//MyApp//example.com//",
"-//My App//NS9 Calendar//EN",
"-//SharePoint//NONSGML v1.0//EN",
"-//YourCassavaLtd//EateriesDept//EN",
"-//Your App//EN",
"-//Organization//EN",
"-//Calendar Auto//EN",
"-Meeting Schedule",
"-//JANSANI//Email Engine v12.7//EN",
"-Event Mandate",
"-//CalendarInviteBuilder//EN",
"-//CustomMailer//EN",
"Trafft",
"-//caldav.icloud.com//CALDAVJ 2620B879//EN",
"-//Calendar Event//EN",
"-//dilmar//EN",
"-//First Dips//Portal//EN",
"-//X7fG3//Y2kL9//M9nP4 16.0 MIMEDIR//EN",
"-//HRNotify//CompChange 1.0//EN",
"-//Prof Morales Sender//EN",
"//NONSGML Event//EN"
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing ICS calendar attachments that have product identifiers matching patterns commonly associated with malicious calendar invitations. The rule identifies ICS files through multiple detection methods and analyzes the product_id field for suspicious formatting that may indicate automated generation or spoofing attempts.
- inbound message
any of
attachmentswhere 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(.).product_id matches '-//[a-z0-9]*[0-9][a-z0-9]*//EN'
beta.file.parse_ics(.).product_id contains any of 21 patterns
-//MyApp//example.com//-//My App//NS9 Calendar//EN-//SharePoint//NONSGML v1.0//EN-//YourCassavaLtd//EateriesDept//EN-//Your App//EN-//Organization//EN-//Calendar Auto//EN-Meeting Schedule-//JANSANI//Email Engine v12.7//EN-Event Mandate-//CalendarInviteBuilder//EN-//CustomMailer//ENTrafft-//caldav.icloud.com//CALDAVJ 2620B879//EN-//Calendar Event//EN-//dilmar//EN-//First Dips//Portal//EN-//X7fG3//Y2kL9//M9nP4 16.0 MIMEDIR//EN-//HRNotify//CompChange 1.0//EN-//Prof Morales Sender//EN//NONSGML Event//EN
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: beta.file.parse_ics, regex.icontains, strings.icontains.
Indicators matched (26)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
regex.icontains | regex | -//[a-z0-9]*[0-9][a-z0-9]*//EN |
strings.icontains | substring | -//MyApp//example.com// |
strings.icontains | substring | -//My App//NS9 Calendar//EN |
strings.icontains | substring | -//SharePoint//NONSGML v1.0//EN |
strings.icontains | substring | -//YourCassavaLtd//EateriesDept//EN |
strings.icontains | substring | -//Your App//EN |
strings.icontains | substring | -//Organization//EN |
strings.icontains | substring | -//Calendar Auto//EN |
14 more
strings.icontains | substring | -Meeting Schedule |
strings.icontains | substring | -//JANSANI//Email Engine v12.7//EN |
strings.icontains | substring | -Event Mandate |
strings.icontains | substring | -//CalendarInviteBuilder//EN |
strings.icontains | substring | -//CustomMailer//EN |
strings.icontains | substring | Trafft |
strings.icontains | substring | -//caldav.icloud.com//CALDAVJ 2620B879//EN |
strings.icontains | substring | -//Calendar Event//EN |
strings.icontains | substring | -//dilmar//EN |
strings.icontains | substring | -//First Dips//Portal//EN |
strings.icontains | substring | -//X7fG3//Y2kL9//M9nP4 16.0 MIMEDIR//EN |
strings.icontains | substring | -//HRNotify//CompChange 1.0//EN |
strings.icontains | substring | -//Prof Morales Sender//EN |
strings.icontains | substring | //NONSGML Event//EN |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
or
beta.file.parse_ics(attachments[]).product_id contains "-//Calendar Auto//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//Calendar Event//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//CalendarInviteBuilder//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//CustomMailer//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//First Dips//Portal//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//HRNotify//CompChange 1.0//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//JANSANI//Email Engine v12.7//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//My App//NS9 Calendar//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//MyApp//example.com//"
beta.file.parse_ics(attachments[]).product_id contains "-//Organization//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//Prof Morales Sender//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//SharePoint//NONSGML v1.0//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//X7fG3//Y2kL9//M9nP4 16.0 MIMEDIR//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//Your App//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//YourCassavaLtd//EateriesDept//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//caldav.icloud.com//CALDAVJ 2620B879//EN"
beta.file.parse_ics(attachments[]).product_id contains "-//dilmar//EN"
beta.file.parse_ics(attachments[]).product_id contains "-Event Mandate"
beta.file.parse_ics(attachments[]).product_id contains "-Meeting Schedule"
beta.file.parse_ics(attachments[]).product_id contains "//NONSGML Event//EN"
beta.file.parse_ics(attachments[]).product_id contains "Trafft"
beta.file.parse_ics(attachments[]).product_id regex_match "-//[a-z0-9]*[0-9][a-z0-9]*//EN"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar file with suspicious UID domain
#Detects inbound messages containing ICS calendar attachments where the event UID property ends with a specific domain (@example.com). Malicious actors may use calendar invites to socially engineer recipients into accepting fraudulent meetings or following malicious instructions embedded in calendar events.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | ICS Phishing, Credential Phishing, BEC/Fraud |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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(.raw_properties,
.key == "UID" and strings.iends_with(.value, "@example.com")
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing ICS calendar attachments where the event UID property ends with a specific domain (@example.com). Malicious actors may use calendar invites to socially engineer recipients into accepting fraudulent meetings or following malicious instructions embedded in calendar events.
- inbound message
any of
attachmentswhere 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(.).eventswhere:any of
.raw_propertieswhere all hold:- .key is 'UID'
- .value ends with '@example.com'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: beta.file.parse_ics, strings.iends_with.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
beta.file.parse_ics(attachments[]).events[].raw_properties[].key | equals | UID |
strings.iends_with | suffix | @example.com |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.file.parse_ics(attachments).events)
any(beta.file.parse_ics(attachments).events.raw_properties)
and
beta.file.parse_ics(attachments[]).events[].raw_properties[].key eq "UID"
beta.file.parse_ics(attachments[]).events[].raw_properties[].value ends_with "@example.com"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS calendar with embedded file from internal sender with SPF failure
#Detects calendar invitations (ICS files) from internal domains that fail SPF authentication and contain embedded attachments, with single attendee and organizer both from organizational domains.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Spoofing, Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and sender.email.domain.domain in $org_domains
and not coalesce(headers.auth_summary.dmarc.pass, false)
// has an ICS file
and any(attachments,
.file_extension == "ics" or .content_type == "text/calendar"
)
// and a single other attachment that isn't an ICS but is embedded in the ICS
and length(filter(attachments,
not (
.file_extension == "ics"
or .content_type == "text/calendar"
or .file_type in $file_types_images
)
and any(filter(attachments,
.file_extension == "ics"
or .content_type == "text/calendar"
),
strings.contains(file.parse_text(.).text,
..content_id
)
)
)
) == 1
// exlode the ics file and look at the VEVENT file
and any(filter(attachments,
.file_extension == "ics" or .content_type == "text/calendar"
),
any(file.explode(.),
// attendees and org are both within org_domains
any(.scan.ics.calendars,
any(.components,
.type == "VEVENT"
and length(.attendees) == 1
and all(.attendees,
.mailbox.email.domain.domain in $org_domains
)
and any(.organizers,
.mailbox.email.domain.domain in $org_domains
)
and length(.attachments) > 0
and all(.attachments,
.type == "uri" and strings.starts_with(.uri, "CID:")
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects calendar invitations (ICS files) from internal domains that fail SPF authentication and contain embedded attachments, with single attendee and organizer both from organizational domains.
- inbound message
- sender.email.domain.domain in $org_domains
not:
- coalesce(headers.auth_summary.dmarc.pass)
any of
attachmentswhere any holds:- .file_extension is 'ics'
- .content_type is 'text/calendar'
- length(filter(attachments, not .file_extension == 'ics' or .content_type == 'text/calendar' or .file_type in $file_types_images and any(filter(attachments, .file_extension == 'ics' or .content_type == 'text/calendar'), strings.contains(file.parse_text(.).text, ..content_id)))) is 1
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.ics.calendarswhere:any of
.componentswhere all hold:- .type is 'VEVENT'
- length(.attendees) is 1
all of
.attendeeswhere:- .mailbox.email.domain.domain in $org_domains
any of
.organizerswhere:- .mailbox.email.domain.domain in $org_domains
- length(.attachments) > 0
all of
.attachmentswhere all hold:- .type is 'uri'
- .uri starts with 'CID:'
Inspects: attachments[].content_id, attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.domain, type.inbound. Sensors: file.explode, file.parse_text, strings.contains, strings.starts_with. Reference lists: $file_types_images, $org_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
attachments[].content_type | equals | text/calendar |
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].type | equals | VEVENT |
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attachments[].type | equals | uri |
strings.starts_with | prefix | CID: |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.ics.calendars)
any(file.explode(filter(attachments)).scan.ics.calendars.components)
and
any(file.explode(filter(attachments)).scan.ics.calendars.components.organizers)
macro "file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].organizers[].mailbox.email.domain.domain in org_domains"
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attachments length_compare "0"
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attendees length_compare "1"
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].type eq "VEVENT"
macro "all(file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attachments)"
macro "all(file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attendees)"
any(attachments)
or
attachments.content_type eq "text/calendar"
attachments.file_extension eq "ics"
not
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
filter(attachments, not .file_extension == 'ics' or .content_type == 'text/calendar' or .file_type in $file_types_images and any(filter(attachments, .file_extension == 'ics' or .content_type == 'text/calendar'), strings.contains(file.parse_text(.).text, ..content_id))) length_compare "1"
type.inbound eq "true"
macro "sender.email.domain.domain in org_domains"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS file with AWS Lambda URL
#Detects ICS calendar files that contain references to AWS Lambda URLs, which may be used to deliver malicious content or redirect users to suspicious resources.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, Free file host, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ('ics')
or .content_type in ("application/ics", "text/calendar")
)
and (
regex.icontains(file.parse_text(.).text, 'lambda-url')
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
or any(beta.file.parse_ics(.).events,
any(.links,
strings.icontains(.href_url.domain.domain, "lambda-url")
)
)
)
)
Detection logic
Scope: inbound message.
Detects ICS calendar files that contain references to AWS Lambda URLs, which may be used to deliver malicious content or redirect users to suspicious resources.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('ics')
- .content_type in ('application/ics', 'text/calendar')
any of:
- file.parse_text(.).text matches 'lambda-url'
any of
beta.file.parse_ics(.).eventswhere:any of
.linkswhere:- .href_url.domain.domain contains 'lambda-url'
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: beta.file.parse_ics, file.parse_text, regex.icontains, strings.icontains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
regex.icontains | regex | lambda-url |
strings.icontains | substring | lambda-url |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
any(beta.file.parse_ics(attachments).events)
any(beta.file.parse_ics(attachments).events.links)
beta.file.parse_ics(attachments).events.links.href_url.domain.domain contains "lambda-url"
file.parse_text(attachments[]).text regex_match "lambda-url"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS file with excessive custom properties
#ICS calendar attachment contains an unusually high number of custom X- properties, which may indicate attempts to hide malicious content or exploit calendar parsing vulnerabilities.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments,
.file_type in~ ('ics')
or .content_type in ("text/calendar", "application/ics")
),
regex.icount(file.parse_text(.).text,
'[\r\n]X-[^\r\n]+\x3b\s?[^\r\n]+:\s*[a-f0-9]{32,}'
) > 10
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
or any(beta.file.parse_ics(.).events,
length(filter(.raw_properties,
strings.istarts_with(.key, 'X-')
and regex.icontains(.value, '^[a-f0-9]{32,}$')
)
) > 10
)
)
Detection logic
Scope: inbound message.
ICS calendar attachment contains an unusually high number of custom X- properties, which may indicate attempts to hide malicious content or exploit calendar parsing vulnerabilities.
- inbound message
any of
filter(attachments)where any holds:- regex.icount(file.parse_text(.).text, '[\\r\\n]X-[^\\r\\n]+\\x3b\\s?[^\\r\\n]+:\\s*[a-f0-9]{32,}') > 10
any of
beta.file.parse_ics(.).eventswhere:- length(filter(.raw_properties, strings.istarts_with(.key, 'X-') and regex.icontains(.value, '^[a-f0-9]{32,}$'))) > 10
Inspects: attachments[].content_type, attachments[].file_type, type.inbound. Sensors: beta.file.parse_ics, file.parse_text, regex.icontains, regex.icount, strings.istarts_with.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | ics |
attachments[].content_type | member | text/calendar |
attachments[].content_type | member | application/ics |
regex.icount | regex | [\r\n]X-[^\r\n]+\x3b\s?[^\r\n]+:\s*[a-f0-9]{32,} |
strings.istarts_with | prefix | X- |
regex.icontains | regex | ^[a-f0-9]{32,}$ |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
or
any(beta.file.parse_ics(filter(attachments)).events)
filter(beta.file.parse_ics(filter(attachments)[]).events[].raw_properties, strings.istarts_with(beta.file.parse_ics(filter(attachments)[]).events[].key, 'X-') and regex.icontains(beta.file.parse_ics(filter(attachments)[]).events[].value, '^[a-f0-9]{32,}$')) length_compare "10"
regex.icount func_call "regex.icount(file.parse_text(filter(attachments)[]).text, \"[\\r\\n]X-[^\\r\\n]+\\x3b\\s?[^\\r\\n]+:\\s*[a-f0-9]{32,}\") > 10"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS file with links to newly registered domains
#Detects calendar invite attachments (ICS files) containing links to domains registered within the last 30 days, which may indicate malicious calendar invitations designed to redirect users to suspicious websites.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 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, network.whois(.href_url.domain).days_old < 30)
)
)
Detection logic
Scope: inbound message.
Detects calendar invite attachments (ICS files) containing links to domains registered within the last 30 days, which may indicate malicious calendar invitations designed to redirect users to suspicious websites.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'ics'
any of:
- .file_extension is 'ics'
- .content_type in ('application/ics', 'text/calendar')
any of
beta.file.parse_ics(.).eventswhere:any of
.linkswhere:- network.whois(.href_url.domain).days_old < 30
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: beta.file.parse_ics, network.whois.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | ics |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.file.parse_ics(attachments).events)
any(beta.file.parse_ics(attachments).events.links)
network.whois func_call "network.whois(beta.file.parse_ics(attachments[]).events[].links[].href_url.domain).days_old < 30"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.file_type eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS file with meeting prefix
#Detects incoming messages with a single ICS calendar file attachment that has a filename starting with 'meeting_'.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | ICS Phishing, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and any(filter(attachments,
.file_extension in~ ('ics')
or .content_type in ("application/ics", "text/calendar")
),
regex.icontains(.file_name, 'meeting_[a-zA-Z0-9]{5}\.')
)
Detection logic
Scope: inbound message.
Detects incoming messages with a single ICS calendar file attachment that has a filename starting with 'meeting_'.
- inbound message
- length(attachments) is 1
any of
filter(attachments)where:- .file_name matches 'meeting_[a-zA-Z0-9]{5}\\.'
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: regex.icontains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
regex.icontains | regex | meeting_[a-zA-Z0-9]{5}\. |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
filter(attachments).file_name regex_match "meeting_[a-zA-Z0-9]{5}\\."
attachments length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS file with non-Gregorian calendar scale
#Detects ICS calendar attachments that use a non-standard calendar scale other than GREGORIAN, which may indicate malicious calendar files attempting to exploit calendar parsing vulnerabilities or bypass security filters.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ('ics')
or .content_type in ("application/ics", "text/calendar")
)
and not strings.icontains(beta.file.parse_ics(.).scale, 'GREGORIAN')
)
Detection logic
Scope: inbound message.
Detects ICS calendar attachments that use a non-standard calendar scale other than GREGORIAN, which may indicate malicious calendar files attempting to exploit calendar parsing vulnerabilities or bypass security filters.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('ics')
- .content_type in ('application/ics', 'text/calendar')
not:
- beta.file.parse_ics(.).scale contains 'GREGORIAN'
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: beta.file.parse_ics, strings.icontains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
not
beta.file.parse_ics(attachments[]).scale contains "GREGORIAN"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS with embedded document
#ICS invite contains an embedded document.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension == "ics"
and strings.ilike(file.parse_text(.).text,
'*ATTACH;ENCODING=*;VALUE=BINARY*'
)
and (
strings.ilike(file.parse_text(.).text, '*FILENAME=*.doc*')
or strings.ilike(file.parse_text(.).text, '*FILENAME=*.dot*')
or strings.ilike(file.parse_text(.).text, '*FILENAME=*.pp*')
or strings.ilike(file.parse_text(.).text, '*FILENAME=*.wbk*')
or strings.ilike(file.parse_text(.).text, '*FILENAME=*.xl*')
or strings.ilike(file.parse_text(.).text, '*FILENAME=*.html*')
)
)
Detection logic
Scope: inbound message.
ICS invite contains an embedded document.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'ics'
- file.parse_text(.).text matches '*ATTACH;ENCODING=*;VALUE=BINARY*'
file.parse_text(.).text matches any of 6 patterns
*FILENAME=*.doc**FILENAME=*.dot**FILENAME=*.pp**FILENAME=*.wbk**FILENAME=*.xl**FILENAME=*.html*
Inspects: attachments[].file_extension, type.inbound. Sensors: file.parse_text, strings.ilike.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
strings.ilike | substring | *ATTACH;ENCODING=*;VALUE=BINARY* |
strings.ilike | substring | *FILENAME=*.doc* |
strings.ilike | substring | *FILENAME=*.dot* |
strings.ilike | substring | *FILENAME=*.pp* |
strings.ilike | substring | *FILENAME=*.wbk* |
strings.ilike | substring | *FILENAME=*.xl* |
strings.ilike | substring | *FILENAME=*.html* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
file.parse_text(attachments[]).text wildcard "*FILENAME=*.doc*"
file.parse_text(attachments[]).text wildcard "*FILENAME=*.dot*"
file.parse_text(attachments[]).text wildcard "*FILENAME=*.html*"
file.parse_text(attachments[]).text wildcard "*FILENAME=*.pp*"
file.parse_text(attachments[]).text wildcard "*FILENAME=*.wbk*"
file.parse_text(attachments[]).text wildcard "*FILENAME=*.xl*"
attachments.file_extension eq "ics"
file.parse_text(attachments[]).text wildcard "*ATTACH;ENCODING=*;VALUE=BINARY*"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS with embedded Javascript in SVG file
#Detects incoming messages containing ICS attachments with embedded SVG files that contain malicious JavaScript code, including base64-encoded content and potentially harmful event handlers. The rule specifically watches for onload events, location redirects, error handlers, and iframe elements with base64 data URIs.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Scripting, Evasion, ICS Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ('ics')
or .content_type in ("application/ics", "text/calendar")
)
and any(file.explode(.),
(
.file_extension in~ ("svg", "svgz")
or .flavors.mime == "image/svg+xml"
)
and any(.scan.strings.strings,
strings.ilike(.,
"*onload*",
"*window.location.href*",
"*onerror*",
"*CDATA*",
"*<script*",
"*</script*",
"*atob*",
"*location.assign*",
"*decodeURIComponent*"
)
)
)
)
Detection logic
Scope: inbound message.
Detects incoming messages containing ICS attachments with embedded SVG files that contain malicious JavaScript code, including base64-encoded content and potentially harmful event handlers. The rule specifically watches for onload events, location redirects, error handlers, and iframe elements with base64 data URIs.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('ics')
- .content_type in ('application/ics', 'text/calendar')
any of
file.explode(.)where all hold:any of:
- .file_extension in ('svg', 'svgz')
- .flavors.mime is 'image/svg+xml'
any of
.scan.strings.stringswhere:. matches any of 9 patterns
*onload**window.location.href**onerror**CDATA**<script**</script**atob**location.assign**decodeURIComponent*
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike.
Indicators matched (15)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ics |
attachments[].content_type | member | application/ics |
attachments[].content_type | member | text/calendar |
file.explode(attachments[])[].file_extension | member | svg |
file.explode(attachments[])[].file_extension | member | svgz |
file.explode(attachments[])[].flavors.mime | equals | image/svg+xml |
strings.ilike | substring | *onload* |
strings.ilike | substring | *window.location.href* |
strings.ilike | substring | *onerror* |
strings.ilike | substring | *CDATA* |
strings.ilike | substring | *<script* |
strings.ilike | substring | *</script* |
3 more
strings.ilike | substring | *atob* |
strings.ilike | substring | *location.assign* |
strings.ilike | substring | *decodeURIComponent* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "</script"
file.explode(attachments[])[].scan.strings.strings[] match "<script"
file.explode(attachments[])[].scan.strings.strings[] match "CDATA"
file.explode(attachments[])[].scan.strings.strings[] match "atob"
file.explode(attachments[])[].scan.strings.strings[] match "decodeURIComponent"
file.explode(attachments[])[].scan.strings.strings[] match "location.assign"
file.explode(attachments[])[].scan.strings.strings[] match "onerror"
file.explode(attachments[])[].scan.strings.strings[] match "onload"
file.explode(attachments[])[].scan.strings.strings[] match "window.location.href"
or
file.explode(attachments[])[].file_extension in ["svg", "svgz"]
file.explode(attachments[])[].flavors.mime eq "image/svg+xml"
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ICS with employee policy review lure
#Detects ICS calendar attachments containing references to 'policy review' and 'secure access' terminology, which may be used in social engineering attacks to prompt users to take action under the guise of compliance or security requirements.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, BEC/Fraud |
| Tactics and techniques | Evasion, ICS Phishing, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments,
.file_type in~ ('ics')
or .content_type in ("text/calendar", "application/ics")
),
any(file.explode(.),
.depth == 0
and any(.scan.strings.strings,
strings.icontains(., 'policy review')
)
and any(.scan.strings.strings,
strings.icontains(., 'secure access')
)
)
)
Detection logic
Scope: inbound message.
Detects ICS calendar attachments containing references to 'policy review' and 'secure access' terminology, which may be used in social engineering attacks to prompt users to take action under the guise of compliance or security requirements.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .depth is 0
any of
.scan.strings.stringswhere:- . contains 'policy review'
any of
.scan.strings.stringswhere:- . contains 'secure access'
Inspects: attachments[].content_type, attachments[].file_type, type.inbound. Sensors: file.explode, strings.icontains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | ics |
attachments[].content_type | member | text/calendar |
attachments[].content_type | member | application/ics |
strings.icontains | substring | policy review |
strings.icontains | substring | secure access |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.strings.strings)
file.explode(filter(attachments)).scan.strings.strings contains "policy review"
any(file.explode(filter(attachments)).scan.strings.strings)
file.explode(filter(attachments)).scan.strings.strings contains "secure access"
file.explode(filter(attachments)[])[].depth eq "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Identity Confirmation With Document Unlock Code
#Detects short inbound messages referencing an attached document that requires the recipient to confirm their identity and enter a code to unlock it, sent within an active thread context.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering, Encryption, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// confirm to unlock language
and strings.icontains(body.current_thread.text, "confirm your identity")
and strings.icontains(body.current_thread.text, "code to unlock document")
// and attached document
and strings.icontains(body.current_thread.text, "attached document")
// short message length
and length(body.current_thread.text) < 500
// plus previous threads
and length(body.previous_threads) > 1
Detection logic
Scope: inbound message.
Detects short inbound messages referencing an attached document that requires the recipient to confirm their identity and enter a code to unlock it, sent within an active thread context.
- inbound message
- body.current_thread.text contains 'confirm your identity'
- body.current_thread.text contains 'code to unlock document'
- body.current_thread.text contains 'attached document'
- length(body.current_thread.text) < 500
- length(body.previous_threads) > 1
Inspects: body.current_thread.text, body.previous_threads, type.inbound. Sensors: strings.icontains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | confirm your identity |
strings.icontains | substring | code to unlock document |
strings.icontains | substring | attached document |
Stages and Predicates
Stage 1: mql_rule
and
body.current_thread.text contains "attached document"
body.current_thread.text contains "code to unlock document"
body.current_thread.text contains "confirm your identity"
body.current_thread.text length_compare "500"
body.previous_threads length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Invoice and W-9 PDFs with suspicious creators
#Detects messages containing two PDF attachments where one has invoice-related naming patterns and another contains W-9 tax form indicators, commonly used in business email compromise attacks targeting financial processes.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Social engineering, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(distinct(attachments, .sha1)) == 2
and length(filter(attachments, .file_type == "pdf")) == 2
// either of them are chrome/wkhtmltopdf
and any(filter(attachments, .file_type == "pdf"),
beta.parse_exif(.).creator == "Chromium"
or strings.icontains(beta.parse_exif(.).creator, "wkhtmltopdf")
or strings.icontains(beta.parse_exif(.).creator, "HeadlessChrome")
or (
any(beta.parse_exif(.).fields, .key == "Creator" and .value == "")
and any(beta.parse_exif(.).fields,
.key == "Producer" and .value == ""
)
)
or any(beta.parse_exif(.).fields,
.key in ("Producer", "CreatorTool")
and regex.icontains(.value, '(?:pdfium|mpdf)')
)
)
and any(attachments,
strings.istarts_with(.file_name, 'lnv')
or strings.istarts_with(.file_name, 'inv-')
or strings.istarts_with(.file_name, "invoice_")
or regex.contains(.file_name, '^Invoice\s\d{8,9}')
or regex.contains(.file_name, '^INV[0-9]{7}')
or regex.contains(.file_name, '^INV#[0-9]{12}')
or regex.icontains(.file_name, '_inv_')
or strings.icontains(beta.ocr(.).text, "Executive Business Coaching")
or strings.icontains(beta.ocr(.).text, "Executive Coaching")
or strings.icontains(beta.ocr(.).text, "Professional Services")
or strings.icontains(beta.ocr(.).text, "Business Systems Integration")
or strings.icontains(beta.ocr(.).text, "Consulting & Advisory")
or strings.icontains(beta.ocr(.).text, "Zoomlnfo")
)
and any(attachments,
.file_name == ".pdf"
or regex.contains(beta.ocr(.).text, 'W[=-]9')
or regex.icontains(.file_name, 'w[-_]?9')
)
and not (
sender.email.domain.root_domain in ('intuit.com')
and coalesce(headers.auth_summary.dmarc.pass, false)
)
Detection logic
Scope: inbound message.
Detects messages containing two PDF attachments where one has invoice-related naming patterns and another contains W-9 tax form indicators, commonly used in business email compromise attacks targeting financial processes.
- inbound message
- length(distinct(attachments, .sha1)) is 2
- length(filter(attachments, .file_type == 'pdf')) is 2
any of
filter(attachments)where any holds:- beta.parse_exif(.).creator is 'Chromium'
- beta.parse_exif(.).creator contains 'wkhtmltopdf'
- beta.parse_exif(.).creator contains 'HeadlessChrome'
all of:
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Creator'
- .value is ''
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Producer'
- .value is ''
any of
beta.parse_exif(.).fieldswhere all hold:- .key in ('Producer', 'CreatorTool')
- .value matches '(?:pdfium|mpdf)'
any of
attachmentswhere any holds:- .file_name starts with 'lnv'
- .file_name starts with 'inv-'
- .file_name starts with 'invoice_'
- .file_name matches '^Invoice\\s\\d{8,9}'
- .file_name matches '^INV[0-9]{7}'
- .file_name matches '^INV#[0-9]{12}'
- .file_name matches '_inv_'
- beta.ocr(.).text contains 'Executive Business Coaching'
- beta.ocr(.).text contains 'Executive Coaching'
- beta.ocr(.).text contains 'Professional Services'
- beta.ocr(.).text contains 'Business Systems Integration'
- beta.ocr(.).text contains 'Consulting & Advisory'
- beta.ocr(.).text contains 'Zoomlnfo'
any of
attachmentswhere any holds:- .file_name is '.pdf'
- beta.ocr(.).text matches 'W[=-]9'
- .file_name matches 'w[-_]?9'
not:
all of:
- sender.email.domain.root_domain in ('intuit.com')
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_name, attachments[].file_type, attachments[].sha1, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.ocr, beta.parse_exif, regex.contains, regex.icontains, strings.icontains, strings.istarts_with.
Indicators matched (25)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | wkhtmltopdf |
strings.icontains | substring | HeadlessChrome |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | Creator |
beta.parse_exif(filter(attachments)[]).fields[].value | equals | |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | Producer |
beta.parse_exif(filter(attachments)[]).fields[].key | member | Producer |
beta.parse_exif(filter(attachments)[]).fields[].key | member | CreatorTool |
regex.icontains | regex | (?:pdfium|mpdf) |
strings.istarts_with | prefix | lnv |
strings.istarts_with | prefix | inv- |
strings.istarts_with | prefix | invoice_ |
13 more
regex.contains | regex | ^Invoice\s\d{8,9} |
regex.contains | regex | ^INV[0-9]{7} |
regex.contains | regex | ^INV#[0-9]{12} |
regex.icontains | regex | _inv_ |
strings.icontains | substring | Executive Business Coaching |
strings.icontains | substring | Executive Coaching |
strings.icontains | substring | Professional Services |
strings.icontains | substring | Business Systems Integration |
strings.icontains | substring | Consulting & Advisory |
strings.icontains | substring | Zoomlnfo |
attachments[].file_name | equals | .pdf |
regex.contains | regex | W[=-]9 |
regex.icontains | regex | w[-_]?9 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
or
and
any(beta.parse_exif(filter(attachments)).fields)
and
beta.parse_exif(filter(attachments)[]).fields[].key eq "Creator"
beta.parse_exif(filter(attachments)[]).fields[].value eq ""
any(beta.parse_exif(filter(attachments)).fields)
and
beta.parse_exif(filter(attachments)[]).fields[].key eq "Producer"
beta.parse_exif(filter(attachments)[]).fields[].value eq ""
any(beta.parse_exif(filter(attachments)).fields)
and
beta.parse_exif(filter(attachments)[]).fields[].key in ["CreatorTool", "Producer"]
beta.parse_exif(filter(attachments)[]).fields[].value regex_match "(?:pdfium|mpdf)"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).creator == Chromium"
beta.parse_exif(filter(attachments)[]).creator contains "HeadlessChrome"
beta.parse_exif(filter(attachments)[]).creator contains "wkhtmltopdf"
any(attachments)
or
attachments.file_name eq ".pdf"
attachments.file_name regex_match "w[-_]?9"
beta.ocr(attachments[]).text regex_match "W[=-]9"
any(attachments)
or
attachments.file_name regex_match "^INV#[0-9]{12}"
attachments.file_name regex_match "^INV[0-9]{7}"
attachments.file_name regex_match "^Invoice\\s\\d{8,9}"
attachments.file_name regex_match "_inv_"
attachments.file_name starts_with "inv-"
attachments.file_name starts_with "invoice_"
attachments.file_name starts_with "lnv"
beta.ocr(attachments[]).text contains "Business Systems Integration"
beta.ocr(attachments[]).text contains "Consulting & Advisory"
beta.ocr(attachments[]).text contains "Executive Business Coaching"
beta.ocr(attachments[]).text contains "Executive Coaching"
beta.ocr(attachments[]).text contains "Professional Services"
beta.ocr(attachments[]).text contains "Zoomlnfo"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
sender.email.domain.root_domain eq "intuit.com"
distinct(attachments, .sha1) length_compare "2"
filter(attachments, .file_type == 'pdf') length_compare "2"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | eq | intuit.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"intuit.com" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: JavaScript file with suspicious base64-encoded executable
#JavaScript attachment or compressed JavaScript file containing a base64 encoded executable.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
or .file_extension in ("js", "jar")
)
and any(file.explode(.),
(
(
.file_extension in ("js", "jar")
or any(.flavors.yara, . == "javascript_file")
)
and any(.flavors.yara, . == 'base64_pe')
)
)
)
Detection logic
Scope: inbound message.
JavaScript attachment or compressed JavaScript file containing a base64 encoded executable.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_extension in ('js', 'jar')
any of
file.explode(.)where all hold:any of:
- .file_extension in ('js', 'jar')
any of
.flavors.yarawhere:- . is 'javascript_file'
any of
.flavors.yarawhere:- . is 'base64_pe'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | js |
attachments[].file_extension | member | jar |
file.explode(attachments[])[].file_extension | member | js |
file.explode(attachments[])[].file_extension | member | jar |
file.explode(attachments[])[].flavors.yara[] | equals | javascript_file |
file.explode(attachments[])[].flavors.yara[] | equals | base64_pe |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "javascript_file"
file.explode(attachments[])[].file_extension in ["jar", "js"]
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "base64_pe"
or
attachments.file_extension in ["jar", "js"]
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: JPEG with gd-jpeg creator and suspicious file name
#Detects inbound messages containing a single JPEG attachment with specific filename patterns and EXIF metadata indicating creation by gd-jpeg v1.0. This has been observed being used to produce company logos used within phishing messages.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type == "jpg")) == 1
and any(attachments,
.file_type == "jpg"
and .file_extension == "jpeg"
and strings.icontains(.file_name, 'images')
and (
strings.count(.file_name, '/') == 1
or strings.count(.file_name, 'image') == 2
)
and any(beta.parse_exif(.).fields,
.key =~ "Comment"
and strings.istarts_with(.value, 'CREATOR: gd-jpeg v1.0')
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing a single JPEG attachment with specific filename patterns and EXIF metadata indicating creation by gd-jpeg v1.0. This has been observed being used to produce company logos used within phishing messages.
- inbound message
- length(filter(attachments, .file_type == 'jpg')) is 1
any of
attachmentswhere all hold:- .file_type is 'jpg'
- .file_extension is 'jpeg'
- .file_name contains 'images'
any of:
- strings.count(.file_name, '/') is 1
- strings.count(.file_name, 'image') is 2
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Comment'
- .value starts with 'CREATOR: gd-jpeg v1.0'
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, type.inbound. Sensors: beta.parse_exif, strings.count, strings.icontains, strings.istarts_with.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | jpg |
attachments[].file_extension | equals | jpeg |
strings.icontains | substring | images |
beta.parse_exif(attachments[]).fields[].key | equals | Comment |
strings.istarts_with | prefix | CREATOR: gd-jpeg v1.0 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.parse_exif(attachments).fields)
and
beta.parse_exif(attachments[]).fields[].key eq "Comment"
beta.parse_exif(attachments[]).fields[].value starts_with "CREATOR: gd-jpeg v1.0"
or
strings.count func_call "strings.count(attachments[].file_name, \"/\") == 1"
strings.count func_call "strings.count(attachments[].file_name, \"image\") == 2"
attachments.file_extension eq "jpeg"
attachments.file_name contains "images"
attachments.file_type eq "jpg"
filter(attachments, .file_type == 'jpg') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Legal themed message or PDF with suspicious indicators
#Detects messages with short body content or emoji containing PDF attachments from suspicious creators that include legal and compliance language with embedded malicious links, URL shorteners, or newly registered domains.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Extortion, BEC/Fraud |
| Tactics and techniques | Evasion, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// short body or contains emoji
and (
length(body.current_thread.text) < 1500
or regex.contains(body.plain.raw,
'[\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}]'
)
or regex.contains(subject.base,
'[\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}]'
)
)
// is not a reply
and length(headers.references) == 0
and headers.in_reply_to is null
and (
( // only one attachment
length(attachments) == 1
// or, any 2 attachments share the ~same file name
or any(attachments,
any(regex.extract(.file_name,
// the regex extracts the file name, discarding the file extention and any numbers in parens
// "test.txt" and "test (1).pdf" become "test"
'(?P<file_name>.*?)(?:\s*\([^)]+\))*\.[^.]+$'
),
length(filter(attachments,
strings.istarts_with(.file_name,
..named_groups["file_name"]
)
)
) > 1
)
)
)
// suspicious creator
and any(attachments,
(.file_extension == "pdf" or .file_type == "pdf")
and any(file.explode(.),
strings.ilike(.scan.exiftool.producer,
"*Google Docs Renderer*",
"*Skia/PDF*",
"*Neevia Document Converter*"
)
or strings.istarts_with(.scan.exiftool.creator, "wkhtmltopdf")
)
)
)
and (
// legal language in body with suspicious link in attachment
(
any(ml.nlu_classifier(body.current_thread.text).topics,
.name == "Legal and Compliance" and .confidence in ("medium", "high")
)
and any(attachments,
(.file_extension == "pdf" or .file_type == "pdf")
and any(file.explode(.),
0 < length(.scan.pdf.urls) < 5
and (
any(.scan.pdf.urls,
// with links that are URL shortners
.domain.root_domain in $url_shorteners
or .domain.domain in $url_shorteners
or network.whois(.domain).days_old < 14
// when visiting those links, the link it is sus
or ml.link_analysis(.).effective_url.domain.tld in $suspicious_tlds
or ml.link_analysis(.).credphish.contains_captcha
or ml.link_analysis(.).credphish.disposition == "phishing"
or strings.icontains(ml.link_analysis(.).final_dom.display_text,
"I'm Human"
)
)
)
)
)
)
// no body text, legal language in attachment
or (
length(body.current_thread.text) < 50
and any(attachments,
(.file_extension == "pdf" or .file_type == "pdf")
and any(file.explode(.),
(
length(ml.nlu_classifier(.scan.ocr.raw).topics) == 1
and any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name == "Legal and Compliance"
and .confidence in ("medium", "high")
)
and not any(ml.nlu_classifier(.scan.ocr.raw).entities,
.name == "sender"
and .text =~ sender.display_name
)
)
// foreign language indicators
or regex.icontains(.scan.ocr.raw,
'pornograph(y|ie)',
'interpol\b',
'europol',
'dissuade',
// French indicators, seen in threatening language
'ce jeu en ligne',
'vraie vie'
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects messages with short body content or emoji containing PDF attachments from suspicious creators that include legal and compliance language with embedded malicious links, URL shorteners, or newly registered domains.
- inbound message
any of:
- length(body.current_thread.text) < 1500
- body.plain.raw 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}]'
- subject.base 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}]'
- length(headers.references) is 0
- headers.in_reply_to is missing
all of:
any of:
- length(attachments) is 1
any of
attachmentswhere:any of
regex.extract(.file_name)where:- length(filter(attachments, strings.istarts_with(.file_name, .named_groups['file_name']))) > 1
any of
attachmentswhere all hold:any of:
- .file_extension is 'pdf'
- .file_type is 'pdf'
any of
file.explode(.)where any holds:.scan.exiftool.producer matches any of 3 patterns
*Google Docs Renderer**Skia/PDF**Neevia Document Converter*
- .scan.exiftool.creator starts with 'wkhtmltopdf'
any of:
all of:
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name is 'Legal and Compliance'
- .confidence in ('medium', 'high')
any of
attachmentswhere all hold:any of:
- .file_extension is 'pdf'
- .file_type is 'pdf'
any of
file.explode(.)where all hold:all of:
- length(.scan.pdf.urls) > 0
- length(.scan.pdf.urls) < 5
any of
.scan.pdf.urlswhere any holds:- .domain.root_domain in $url_shorteners
- .domain.domain in $url_shorteners
- network.whois(.domain).days_old < 14
- ml.link_analysis(.).effective_url.domain.tld in $suspicious_tlds
- ml.link_analysis(.).credphish.contains_captcha
- ml.link_analysis(.).credphish.disposition is 'phishing'
- ml.link_analysis(.).final_dom.display_text contains "I'm Human"
all of:
- length(body.current_thread.text) < 50
any of
attachmentswhere all hold:any of:
- .file_extension is 'pdf'
- .file_type is 'pdf'
any of
file.explode(.)where any holds:all of:
- length(ml.nlu_classifier(.scan.ocr.raw).topics) is 1
any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere all hold:- .name is 'Legal and Compliance'
- .confidence in ('medium', 'high')
not:
any of
ml.nlu_classifier(.scan.ocr.raw).entitieswhere all hold:- .name is 'sender'
- .text is sender.display_name
.scan.ocr.raw matches any of 6 patterns
pornograph(y|ie)interpol\beuropoldissuadece jeu en lignevraie vie
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.plain.raw, headers.in_reply_to, headers.references, sender.display_name, subject.base, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, network.whois, regex.contains, regex.extract, regex.icontains, strings.icontains, strings.ilike, strings.istarts_with. Reference lists: $suspicious_tlds, $url_shorteners.
Indicators matched (21)
| Field | Match | Value |
|---|---|---|
regex.contains | regex | [\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}] |
regex.extract | regex | (?P<file_name>.*?)(?:\s*\([^)]+\))*\.[^.]+$ |
attachments[].file_extension | equals | pdf |
attachments[].file_type | equals | pdf |
strings.ilike | substring | *Google Docs Renderer* |
strings.ilike | substring | *Skia/PDF* |
strings.ilike | substring | *Neevia Document Converter* |
strings.istarts_with | prefix | wkhtmltopdf |
ml.nlu_classifier(body.current_thread.text).topics[].name | equals | Legal and Compliance |
ml.nlu_classifier(body.current_thread.text).topics[].confidence | member | medium |
ml.nlu_classifier(body.current_thread.text).topics[].confidence | member | high |
strings.icontains | substring | I'm Human |
9 more
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name | equals | Legal and Compliance |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence | member | medium |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence | member | high |
regex.icontains | regex | pornograph(y|ie) |
regex.icontains | regex | interpol\b |
regex.icontains | regex | europol |
regex.icontains | regex | dissuade |
regex.icontains | regex | ce jeu en ligne |
regex.icontains | regex | vraie vie |
Stages and Predicates
Stage 1: mql_rule
and
or
and
any(attachments)
and
any(file.explode(attachments))
or
and
not
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].name eq "sender"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].text cross_field_compare "sender.display_name"
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).topics)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence in ["high", "medium"]
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name eq "Legal and Compliance"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics length_compare "1"
file.explode(attachments[])[].scan.ocr.raw regex_match "ce jeu en ligne"
file.explode(attachments[])[].scan.ocr.raw regex_match "dissuade"
file.explode(attachments[])[].scan.ocr.raw regex_match "europol"
file.explode(attachments[])[].scan.ocr.raw regex_match "interpol\\b"
file.explode(attachments[])[].scan.ocr.raw regex_match "pornograph(y|ie)"
file.explode(attachments[])[].scan.ocr.raw regex_match "vraie vie"
or
attachments.file_extension eq "pdf"
attachments.file_type eq "pdf"
body.current_thread.text length_compare "50"
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.pdf.urls)
or
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.pdf.urls[]).credphish.contains_captcha"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.pdf.urls[]).credphish.disposition == phishing"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.pdf.urls[]).effective_url.domain.tld in suspicious_tlds"
ml.link_analysis(file.explode(attachments[])[].scan.pdf.urls[]).final_dom.display_text contains "I'm Human"
network.whois func_call "network.whois(file.explode(attachments[])[].scan.pdf.urls[].domain).days_old < 14"
macro "file.explode(attachments[])[].scan.pdf.urls[].domain.domain in url_shorteners"
macro "file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain in url_shorteners"
file.explode(attachments[])[].scan.pdf.urls length_compare "0"
file.explode(attachments[])[].scan.pdf.urls length_compare "5"
or
attachments.file_extension eq "pdf"
attachments.file_type eq "pdf"
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 eq "Legal and Compliance"
any(attachments)
and
any(file.explode(attachments))
or
file.explode(attachments[])[].scan.exiftool.creator starts_with "wkhtmltopdf"
file.explode(attachments[])[].scan.exiftool.producer match "Google Docs Renderer"
file.explode(attachments[])[].scan.exiftool.producer match "Neevia Document Converter"
file.explode(attachments[])[].scan.exiftool.producer match "Skia/PDF"
or
attachments.file_extension eq "pdf"
attachments.file_type eq "pdf"
or
any(attachments)
any(regex.extract(attachments.file_name))
filter(attachments, strings.istarts_with(regex.extract(attachments[].file_name)[].file_name, attachments[].named_groups['file_name'])) length_compare "1"
attachments length_compare "1"
or
body.current_thread.text length_compare "1500"
body.plain.raw 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}]"
subject.base 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}]"
headers.in_reply_to is_null
headers.references length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.plain.raw | regex_match |
| field:"body.plain.raw" kind:regex_match value:"[\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}]" |
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
subject.base | regex_match |
| field:"subject.base" kind:regex_match value:"[\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}]" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Link file with UNC path
#Attached link file contains a UNC path. This can be used to relay NTLM password hashes; Windows will attempt to authenticate against the path even without the file being opened.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, LNK |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in ("lnk", "url")
and any(file.explode(.),
any(.scan.strings.strings,
regex.icontains(.,
'\\\\([a-zA-Z0-9_:%.$-]+)\\([a-zA-Z0-9_:%.$-]+)'
)
) // normal UNC paths
or any(.scan.strings.strings,
regex.icontains(.,
'%5C%5C([a-zA-Z0-9_:%.$-]+)%5C([a-zA-Z0-9_:%.$-]+)'
)
) // percent-encoded UNC paths
)
)
Detection logic
Scope: inbound message.
Attached link file contains a UNC path. This can be used to relay NTLM password hashes; Windows will attempt to authenticate against the path even without the file being opened.
- inbound message
any of
attachmentswhere all hold:- .file_extension in ('lnk', 'url')
any of
file.explode(.)where any holds:any of
.scan.strings.stringswhere:- . matches '\\\\\\\\([a-zA-Z0-9_:%.$-]+)\\\\([a-zA-Z0-9_:%.$-]+)'
any of
.scan.strings.stringswhere:- . matches '%5C%5C([a-zA-Z0-9_:%.$-]+)%5C([a-zA-Z0-9_:%.$-]+)'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, regex.icontains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | lnk |
attachments[].file_extension | member | url |
regex.icontains | regex | \\\\([a-zA-Z0-9_:%.$-]+)\\([a-zA-Z0-9_:%.$-]+) |
regex.icontains | regex | %5C%5C([a-zA-Z0-9_:%.$-]+)%5C([a-zA-Z0-9_:%.$-]+) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "%5C%5C([a-zA-Z0-9_:%.$-]+)%5C([a-zA-Z0-9_:%.$-]+)"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "\\\\\\\\([a-zA-Z0-9_:%.$-]+)\\\\([a-zA-Z0-9_:%.$-]+)"
attachments.file_extension in ["lnk", "url"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Link to Doubleclick.net open redirect
#Doubleclick.net link in a document leveraging an open redirect.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Evasion, Open redirect, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(body.links) == 0
and any(attachments,
(.file_type in ("pdf", "doc", "docx"))
and any(file.explode(.),
any(.scan.url.urls,
.domain.root_domain == "doubleclick.net"
and (
strings.icontains(.path, "/aclk")
or strings.icontains(.path, "/pcs/click")
or strings.icontains(.path, "/searchads/link/click")
)
and regex.icontains(.query_params,
'&(?:adurl|ds_dest_url)=(?:[a-z]+(?:\:|%3a))?(?:\/|%2f)(?:\/|%2f)'
)
)
)
)
Detection logic
Scope: inbound message.
Doubleclick.net link in a document leveraging an open redirect.
- inbound message
- length(body.links) is 0
any of
attachmentswhere all hold:- .file_type in ('pdf', 'doc', 'docx')
any of
file.explode(.)where:any of
.scan.url.urlswhere all hold:- .domain.root_domain is 'doubleclick.net'
any of:
- .path contains '/aclk'
- .path contains '/pcs/click'
- .path contains '/searchads/link/click'
- .query_params matches '&(?:adurl|ds_dest_url)=(?:[a-z]+(?:\\:|%3a))?(?:\\/|%2f)(?:\\/|%2f)'
Inspects: attachments[].file_type, body.links, type.inbound. Sensors: file.explode, regex.icontains, strings.icontains.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | pdf |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
file.explode(attachments[])[].scan.url.urls[].domain.root_domain | equals | doubleclick.net |
strings.icontains | substring | /aclk |
strings.icontains | substring | /pcs/click |
strings.icontains | substring | /searchads/link/click |
regex.icontains | regex | &(?:adurl|ds_dest_url)=(?:[a-z]+(?:\:|%3a))?(?:\/|%2f)(?:\/|%2f) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
or
file.explode(attachments[])[].scan.url.urls[].path contains "/aclk"
file.explode(attachments[])[].scan.url.urls[].path contains "/pcs/click"
file.explode(attachments[])[].scan.url.urls[].path contains "/searchads/link/click"
file.explode(attachments[])[].scan.url.urls[].domain.root_domain eq "doubleclick.net"
file.explode(attachments[])[].scan.url.urls[].query_params regex_match "&(?:adurl|ds_dest_url)=(?:[a-z]+(?:\\:|%3a))?(?:\\/|%2f)(?:\\/|%2f)"
attachments.file_type in ["doc", "docx", "pdf"]
body.links length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: LNK file
#Recursively scans files and archives to detect LNK connection files. LNK files can be weaponised to execute arbitrary commands including unpacking and running executable content embedded within the file itself.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | LNK |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension =~ "lnk"
or (
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "lnk")
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect LNK connection files. LNK files can be weaponised to execute arbitrary commands including unpacking and running executable content embedded within the file itself.
- inbound message
any of
attachmentswhere any holds:- .file_extension is 'lnk'
all of:
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'lnk'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | lnk |
file.explode(attachments[])[].file_extension | equals | lnk |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "lnk"
macro "attachments[].file_extension in file_extensions_common_archives"
attachments.file_extension eq "lnk"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: LNK with embedded content
#Emotet has been observed to embed executable content within an LNK file to deliver and execute VBScript when launched. Similar research has demonstrated how this concept may be applied to deliver and launch an embedded executable via PowerShell.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Exploit, LNK, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
.file_extension == "lnk"
and any(file.explode(.),
.file_extension =~ "lnk"
and any(.scan.exiftool.fields,
(.key == "TargetFileSize" and .value == "0")
)
and any(.scan.exiftool.fields,
(
.key == "CommandLineArguments"
and strings.ilike(.value,
"*findstr*",
"*sc $path*",
"*Set-Content*"
)
)
)
)
)
)
Detection logic
Scope: inbound message.
Emotet has been observed to embed executable content within an LNK file to deliver and execute VBScript when launched. Similar research has demonstrated how this concept may be applied to deliver and launch an embedded executable via PowerShell.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'lnk'
any of
file.explode(.)where all hold:- .file_extension is 'lnk'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'TargetFileSize'
- .value is '0'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'CommandLineArguments'
.value matches any of 3 patterns
*findstr**sc $path**Set-Content*
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | lnk |
file.explode(attachments[])[].file_extension | equals | lnk |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | TargetFileSize |
file.explode(attachments[])[].scan.exiftool.fields[].value | equals | 0 |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | CommandLineArguments |
strings.ilike | substring | *findstr* |
strings.ilike | substring | *sc $path* |
strings.ilike | substring | *Set-Content* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.exiftool.fields)
and
or
file.explode(attachments[])[].scan.exiftool.fields[].value match "Set-Content"
file.explode(attachments[])[].scan.exiftool.fields[].value match "findstr"
file.explode(attachments[])[].scan.exiftool.fields[].value match "sc $path"
file.explode(attachments[])[].scan.exiftool.fields[].key eq "CommandLineArguments"
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "TargetFileSize"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "0"
file.explode(attachments[])[].file_extension eq "lnk"
attachments.file_extension eq "lnk"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Macro files containing MHT content
#Detects macro-enabled files that contain embedded MHT (MIME HTML) content, which is commonly used to hide malicious code through file format manipulation.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Evasion, Macros, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in $file_extensions_macros
and any(file.explode(.),
.file_extension == "mht"
and not .flavors.mime == "message/rfc822"
)
)
Detection logic
Scope: inbound message.
Detects macro-enabled files that contain embedded MHT (MIME HTML) content, which is commonly used to hide malicious code through file format manipulation.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .file_extension is 'mht'
not:
- .flavors.mime is 'message/rfc822'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_macros.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].file_extension | equals | mht |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
not
file.explode(attachments[])[].flavors.mime eq "message/rfc822"
file.explode(attachments[])[].file_extension eq "mht"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Macro with suspected use of COM ShellBrowserWindow object for process creation
#Macro references the ShellBrowserWindow COM object which can be used to spawn new processes from Explorer.exe rather than as a child process of the Office application. This can be useful for a threat actor attempting to evade security controls.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(.,
"*new:C08AFD90-F2A1-11D1-8455-00A0C91F3880*"
)
)
)
)
Detection logic
Scope: inbound message.
Macro references the ShellBrowserWindow COM object which can be used to spawn new processes from Explorer.exe rather than as a child process of the Office application. This can be useful for a threat actor attempting to evade security controls.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '*new:C08AFD90-F2A1-11D1-8455-00A0C91F3880*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_macros.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *new:C08AFD90-F2A1-11D1-8455-00A0C91F3880* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "new:C08AFD90-F2A1-11D1-8455-00A0C91F3880"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Malformed OLE file
#Attached OLE file (typically a Microsoft Office document) is malformed, possibly to evade traditional scanners and filters.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in $file_extensions_macros
and any(file.explode(.),
any(.scan.yara.matches, .name == "MALFORMED_OLE_HEADER")
)
)
Detection logic
Scope: inbound message.
Attached OLE file (typically a Microsoft Office document) is malformed, possibly to evade traditional scanners and filters.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_macros
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'MALFORMED_OLE_HEADER'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_macros.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].scan.yara.matches[].name | equals | MALFORMED_OLE_HEADER |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.yara.matches)
file.explode(attachments).scan.yara.matches.name eq "MALFORMED_OLE_HEADER"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Malicious OneNote commands
#Scans for OneNote attachments that contain suspicious commands that may indicate malicious activity.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | OneNote, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ ("one")
or .file_extension in~ $file_extensions_common_archives
)
and any(file.explode(.),
"onenote_file" in .flavors.yara
and any(.scan.strings.strings,
strings.ilike(.,
"*WshShell*",
"*ExecuteCmdAsync*",
"*CreateObject*",
"*Wscript.Shell*",
"*schtasks*",
"*CreateProcess*",
"*winmgmts*",
"*SetEnvironmentVariable*",
"*powershell*",
"*echo off*"
)
)
)
)
Detection logic
Scope: inbound message.
Scans for OneNote attachments that contain suspicious commands that may indicate malicious activity.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('one')
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where all hold:- .flavors.yara contains 'onenote_file'
any of
.scan.strings.stringswhere:. matches any of 10 patterns
*WshShell**ExecuteCmdAsync**CreateObject**Wscript.Shell**schtasks**CreateProcess**winmgmts**SetEnvironmentVariable**powershell**echo off*
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_common_archives.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | one |
file.explode(attachments[])[].flavors.yara | contains | onenote_file |
strings.ilike | substring | *WshShell* |
strings.ilike | substring | *ExecuteCmdAsync* |
strings.ilike | substring | *CreateObject* |
strings.ilike | substring | *Wscript.Shell* |
strings.ilike | substring | *schtasks* |
strings.ilike | substring | *CreateProcess* |
strings.ilike | substring | *winmgmts* |
strings.ilike | substring | *SetEnvironmentVariable* |
strings.ilike | substring | *powershell* |
strings.ilike | substring | *echo off* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "CreateObject"
file.explode(attachments[])[].scan.strings.strings[] match "CreateProcess"
file.explode(attachments[])[].scan.strings.strings[] match "ExecuteCmdAsync"
file.explode(attachments[])[].scan.strings.strings[] match "SetEnvironmentVariable"
file.explode(attachments[])[].scan.strings.strings[] match "Wscript.Shell"
file.explode(attachments[])[].scan.strings.strings[] match "WshShell"
file.explode(attachments[])[].scan.strings.strings[] match "echo off"
file.explode(attachments[])[].scan.strings.strings[] match "powershell"
file.explode(attachments[])[].scan.strings.strings[] match "schtasks"
file.explode(attachments[])[].scan.strings.strings[] match "winmgmts"
file.explode(attachments[])[].flavors.yara contains "onenote_file"
or
attachments.file_extension eq "one"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Malicious zip file matching zipline campaign
#Detects inbound ZIP attachments containing content that matches observed artifacts from a ZipLine campaign reported on by Telekom Security.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | LNK |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "zip"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("zipline_delivery_telekom"))
)
)
Detection logic
Scope: inbound message.
Detects inbound ZIP attachments containing content that matches observed artifacts from a ZipLine campaign reported on by Telekom Security.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('zipline_delivery_telekom')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | zip |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | zipline_delivery_telekom |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "zipline_delivery_telekom"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Microsoft 365 credential phishing
#Looks for messages with an image attachment that contains words related to Microsoft, Office365, and passwords.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type not in $file_types_images)) == 0
and (
any(attachments,
.file_type in $file_types_images
and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft"))
)
or any(attachments,
.file_type in $file_types_images
and any(file.explode(.),
strings.ilike(.scan.ocr.raw, "*microsoft*", "*office")
and length(.scan.ocr.raw) < 1500
)
)
)
and any(attachments,
.file_type in $file_types_images
and any(file.explode(.),
length(filter([
"password",
"unread messages",
"Shared Documents",
"expiration",
"expire",
"expiring",
"kindly",
"renew",
"review",
"emails failed",
"kicked out",
"prevented",
"storage",
"required now",
"cache",
"qr code",
"security update",
"invoice",
"retrieve",
"blocked"
],
strings.icontains(..scan.ocr.raw, .)
)
) >= 2
or (
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence == "high"
)
and length(ml.nlu_classifier(.scan.ocr.raw).entities) > 1
)
)
)
and (
not sender.email.domain.domain in ("microsoft.com", "sharepointonline.com")
or not any(headers.hops,
.authentication_results.compauth.verdict is not null
and .authentication_results.compauth.verdict == "pass"
)
)
// negate angelbeat urls and microsoft disclaimer links
and (
length(body.links) > 0
and not all(body.links,
.href_url.domain.root_domain in (
"abeatinfo.com",
"abeatinvite.com",
"aka.ms",
"angelbeat.com"
)
)
)
// 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
)
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
)
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
Looks for messages with an image attachment that contains words related to Microsoft, Office365, and passwords.
- inbound message
- length(filter(attachments, .file_type not in $file_types_images)) is 0
any of:
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of
ml.logo_detect(.).brandswhere:- .name starts with 'Microsoft'
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of
file.explode(.)where all hold:.scan.ocr.raw matches any of 2 patterns
*microsoft**office
- length(.scan.ocr.raw) < 1500
any of
attachmentswhere all hold:- .file_type in $file_types_images
any of
file.explode(.)where any holds:- length(filter(['password', 'unread messages', 'Shared Documents', 'expiration', 'expire', 'expiring', 'kindly', 'renew', 'review', 'emails failed', 'kicked out', 'prevented', 'storage', 'required now', 'cache', 'qr code', 'security update', 'invoice', 'retrieve', 'blocked'], strings.icontains(.scan.ocr.raw, .))) ≥ 2
all of:
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
- length(ml.nlu_classifier(.scan.ocr.raw).entities) > 1
any of:
not:
- sender.email.domain.domain in ('microsoft.com', 'sharepointonline.com')
not:
any of
headers.hopswhere all hold:- .authentication_results.compauth.verdict is set
- .authentication_results.compauth.verdict is 'pass'
all of:
- length(body.links) > 0
not:
all of
body.linkswhere:- .href_url.domain.root_domain in ('abeatinfo.com', 'abeatinvite.com', 'aka.ms', 'angelbeat.com')
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
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
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
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].authentication_results.compauth.verdict, headers.in_reply_to, headers.references, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.ilike, strings.istarts_with, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
strings.starts_with | prefix | Microsoft |
strings.ilike | substring | *microsoft* |
strings.ilike | substring | *office |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
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"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities length_compare "1"
filter(['password', 'unread messages', 'Shared Documents', 'expiration', 'expire', 'expiring', 'kindly', 'renew', 'review', 'emails failed', 'kicked out', 'prevented', 'storage', 'required now', 'cache', 'qr code', 'security update', 'invoice', 'retrieve', 'blocked'], strings.icontains(attachments[].scan.ocr.raw, file.explode(attachments[])[])) length_compare "2"
macro "attachments[].file_type in file_types_images"
or
any(attachments)
and
any(file.explode(attachments))
and
or
file.explode(attachments[])[].scan.ocr.raw ends_with "office"
file.explode(attachments[])[].scan.ocr.raw match "microsoft"
file.explode(attachments[])[].scan.ocr.raw length_compare "1500"
macro "attachments[].file_type in file_types_images"
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"
or
not
any(headers.hops)
and
headers.hops.authentication_results.compauth.verdict eq "pass"
headers.hops.authentication_results.compauth.verdict is_not_null
not
sender.email.domain.domain in ["microsoft.com", "sharepointonline.com"]
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"
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"
not
macro "all(body.links)"
body.links length_compare "0"
filter(attachments, .file_type not in $file_types_images) length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
headers.in_reply_to | is_null | field:"headers.in_reply_to" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Microsoft impersonation via PDF with link and suspicious language
#Attached PDF contains a Microsoft-affilated logo, suspicious language or keywords, and a link. Known malware delivery method.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Image as content, Impersonation: Brand, PDF, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
(.file_extension == "pdf" or .file_type == "pdf")
and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft"))
)
)
and any(attachments,
(.file_extension == "pdf" or .file_type == "pdf")
and any(file.explode(.),
(
length(filter([
"password",
"unread messages",
"Shared Documents",
"expiration",
"expire",
"expiring",
"kindly",
"renew",
"review",
"emails failed",
"kicked out",
"prevented",
"storage",
"required now",
"cache",
"qr code",
"security update",
"invoice",
"retrieve",
'engine failed',
'OneDrive Error',
'problem connecting',
'secure file',
'access'
],
strings.icontains(..scan.ocr.raw, .)
)
) >= 2
or any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence == "high"
)
)
and (length(.scan.url.urls) > 0 or length(.scan.pdf.urls) > 0)
)
)
and (
not any(headers.hops,
.authentication_results.compauth.verdict is not null
and .authentication_results.compauth.verdict == "pass"
and sender.email.domain.domain in (
"microsoft.com",
"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
)
Detection logic
Scope: inbound message.
Attached PDF contains a Microsoft-affilated logo, suspicious language or keywords, and a link. Known malware delivery method.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'pdf'
- .file_type is 'pdf'
any of
ml.logo_detect(.).brandswhere:- .name starts with 'Microsoft'
any of
attachmentswhere all hold:any of:
- .file_extension is 'pdf'
- .file_type is 'pdf'
any of
file.explode(.)where all hold:any of:
- length(filter(['password', 'unread messages', 'Shared Documents', 'expiration', 'expire', 'expiring', 'kindly', 'renew', 'review', 'emails failed', 'kicked out', 'prevented', 'storage', 'required now', 'cache', 'qr code', 'security update', 'invoice', 'retrieve', 'engine failed', 'OneDrive Error', 'problem connecting', 'secure file', 'access'], strings.icontains(.scan.ocr.raw, .))) ≥ 2
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
any of:
- length(.scan.url.urls) > 0
- length(.scan.pdf.urls) > 0
not:
any of
headers.hopswhere all hold:- .authentication_results.compauth.verdict is set
- .authentication_results.compauth.verdict is 'pass'
- sender.email.domain.domain in ('microsoft.com', 'sharepointonline.com')
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].authentication_results.compauth.verdict, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, strings.icontains, strings.starts_with. Reference lists: $high_trust_sender_root_domains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | Microsoft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).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"
filter(['password', 'unread messages', 'Shared Documents', 'expiration', 'expire', 'expiring', 'kindly', 'renew', 'review', 'emails failed', 'kicked out', 'prevented', 'storage', 'required now', 'cache', 'qr code', 'security update', 'invoice', 'retrieve', 'engine failed', 'OneDrive Error', 'problem connecting', 'secure file', 'access'], strings.icontains(attachments[].scan.ocr.raw, file.explode(attachments[])[])) length_compare "2"
or
file.explode(attachments[])[].scan.pdf.urls length_compare "0"
file.explode(attachments[])[].scan.url.urls length_compare "0"
or
attachments.file_extension eq "pdf"
attachments.file_type eq "pdf"
any(attachments)
and
or
attachments.file_extension eq "pdf"
attachments.file_type eq "pdf"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name 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"
not
any(headers.hops)
and
headers.hops.authentication_results.compauth.verdict eq "pass"
headers.hops.authentication_results.compauth.verdict is_not_null
sender.email.domain.domain in ["microsoft.com", "sharepointonline.com"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: MS Office or RTF file with Shell.Explorer.1 com object with embedded LNK
#Detects embedded Shell.Explorer.1 COM objects containing LNK files within various file types.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_type == "rtf" or .file_extension in $file_extensions_macros)
and any(file.explode(.),
any(.scan.yara.matches,
strings.starts_with(.name, "ShellExplorer1_LNK_")
)
)
)
Detection logic
Scope: inbound message.
Detects embedded Shell.Explorer.1 COM objects containing LNK files within various file types.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type is 'rtf'
- .file_extension in $file_extensions_macros
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name starts with 'ShellExplorer1_LNK_'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.starts_with. Reference lists: $file_extensions_macros.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rtf |
strings.starts_with | prefix | ShellExplorer1_LNK_ |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.yara.matches)
file.explode(attachments).scan.yara.matches.name starts_with "ShellExplorer1_LNK_"
or
attachments.file_type eq "rtf"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: MS OOXML file created by Administrator with zero edit time
#Detects inbound PowerPoint (.pptx) and other MS OOXML attachments where the file creator is listed as 'Administrator' and the total edit time is zero minutes, while missing the 'TitlesOfParts' metadata field. This pattern may indicate programmatically generated or suspicious presentation files.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type in ("pptx", "docx")),
beta.parse_exif(.).creator == "Administrator"
and any(beta.parse_exif(.).fields,
.key == "TotalEditTime" and .value == "0"
)
and not 'TitlesOfParts' in map(beta.parse_exif(.).fields, .key)
)
Detection logic
Scope: inbound message.
Detects inbound PowerPoint (.pptx) and other MS OOXML attachments where the file creator is listed as 'Administrator' and the total edit time is zero minutes, while missing the 'TitlesOfParts' metadata field. This pattern may indicate programmatically generated or suspicious presentation files.
- inbound message
any of
filter(attachments)where all hold:- beta.parse_exif(.).creator is 'Administrator'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'TotalEditTime'
- .value is '0'
not:
- map(...) contains 'TitlesOfParts'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | pptx |
attachments[].file_type | member | docx |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | TotalEditTime |
beta.parse_exif(filter(attachments)[]).fields[].value | equals | 0 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(beta.parse_exif(filter(attachments)).fields)
and
beta.parse_exif(filter(attachments)[]).fields[].key eq "TotalEditTime"
beta.parse_exif(filter(attachments)[]).fields[].value eq "0"
not
map(...) contains "TitlesOfParts"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).creator == Administrator"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: MSI installer file
#Recursively scans files and archives to detect MSI installer files. Coercing a target user to run an MSI can be used as part of an 'IT Support' or 'software update' social engineering attack. Execution of the delivered MSI could enable the attacker to execute malicious code on the target user's host.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments, .file_extension =~ "msi")
or (
any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "msi")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect MSI installer files. Coercing a target user to run an MSI can be used as part of an 'IT Support' or 'software update' social engineering attack. Execution of the delivered MSI could enable the attacker to execute malicious code on the target user's host.
- inbound message
any of:
any of
attachmentswhere:- .file_extension is 'msi'
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'msi'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | msi |
file.explode(attachments[])[].file_extension | equals | msi |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "msi"
macro "attachments[].file_extension in file_extensions_common_archives"
any(attachments)
attachments.file_extension eq "msi"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office document loads remote document template
#Recursively scans archives and Office documents to detect remote document template injection.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
(
// office files
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
.flavors.mime == "text/xml"
and any(.scan.strings.strings,
regex.icontains(., "Target.{0,20}http.{0,200}dotm")
)
)
)
)
Detection logic
Scope: inbound message.
Recursively scans archives and Office documents to detect remote document template injection.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where all hold:- .flavors.mime is 'text/xml'
any of
.scan.strings.stringswhere:- . matches 'Target.{0,20}http.{0,200}dotm'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.explode(attachments[])[].flavors.mime | equals | text/xml |
regex.icontains | regex | Target.{0,20}http.{0,200}dotm |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "Target.{0,20}http.{0,200}dotm"
file.explode(attachments[])[].flavors.mime eq "text/xml"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office document with VSTO add-in
#Recursively scans files and archives to detect Office documents with VSTO Add-ins.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
.file_extension in~ (
"doc",
"docm",
"docx",
"dot",
"dotm",
"xls",
"xlsx",
"xlsm",
"xlm",
"xlsb",
"xlt",
"xltm",
"ppt",
"pptx",
"pptm",
"ppsm"
)
and any(.scan.exiftool.fields,
.key == "Tag_AssemblyLocation"
and strings.ilike(.value, "*.vsto*")
and not strings.ilike(.value, 'C:\Program Files*')
and not any($org_domains, strings.contains(..value, .))
)
)
)
// 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.
Recursively scans files and archives to detect Office documents with VSTO Add-ins.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where all hold:- .file_extension in ('doc', 'docm', 'docx', 'dot', 'dotm', 'xls', 'xlsx', 'xlsm', 'xlm', 'xlsb', 'xlt', 'xltm', 'ppt', 'pptx', 'pptm', 'ppsm')
any of
.scan.exiftool.fieldswhere all hold:- .key is 'Tag_AssemblyLocation'
- .value matches '*.vsto*'
not:
- .value matches 'C:\\Program Files*'
not:
any of
$org_domainswhere:- strings.contains(.value)
any of:
not:
- profile.by_sender().solicited
all of:
- length(headers.reply_to) > 0
all of
headers.reply_towhere:- .email.email not in $recipient_emails
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, headers.reply_to, headers.reply_to[].email.email, type.inbound. Sensors: file.explode, profile.by_sender, strings.contains, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros, $org_domains, $recipient_emails.
Indicators matched (20)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.explode(attachments[])[].file_extension | member | doc |
file.explode(attachments[])[].file_extension | member | docm |
file.explode(attachments[])[].file_extension | member | docx |
file.explode(attachments[])[].file_extension | member | dot |
file.explode(attachments[])[].file_extension | member | dotm |
file.explode(attachments[])[].file_extension | member | xls |
file.explode(attachments[])[].file_extension | member | xlsx |
file.explode(attachments[])[].file_extension | member | xlsm |
file.explode(attachments[])[].file_extension | member | xlm |
file.explode(attachments[])[].file_extension | member | xlsb |
8 more
file.explode(attachments[])[].file_extension | member | xlt |
file.explode(attachments[])[].file_extension | member | xltm |
file.explode(attachments[])[].file_extension | member | ppt |
file.explode(attachments[])[].file_extension | member | pptx |
file.explode(attachments[])[].file_extension | member | pptm |
file.explode(attachments[])[].file_extension | member | ppsm |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | Tag_AssemblyLocation |
strings.ilike | substring | *.vsto* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.exiftool.fields)
and
not
any($org_domains)
strings.contains func_call "strings.contains(file.explode(attachments[])[].scan.exiftool.fields[].value)"
not
file.explode(attachments[])[].scan.exiftool.fields[].value starts_with "C:\\Program Files"
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Tag_AssemblyLocation"
file.explode(attachments[])[].scan.exiftool.fields[].value match ".vsto"
file.explode(attachments[])[].file_extension in ["doc", "docm", "docx", "dot", "dotm", "ppsm", "ppt", "pptm", "pptx", "xlm", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm"]
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office file contains OLE relationship to credential phishing page
#Office file OLE relationship link is a credential page, or contains credential phishing language.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and length(file.oletools(.).relationships) < 500
and any(file.oletools(.).relationships,
(
any(ml.nlu_classifier(ml.link_analysis(.target_url).final_dom.display_text
).intents,
.name == "cred_theft"
and .confidence in ("medium", "high")
)
and .target_url.domain.root_domain not in (
"google.com",
"goo.gl"
)
and ml.link_analysis(.target_url).effective_url.domain.domain != "login.microsoftonline.com"
)
or ml.link_analysis(.target_url).credphish.disposition == "phishing"
)
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
Detection logic
Scope: inbound message.
Office file OLE relationship link is a credential page, or contains credential phishing language.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- length(file.oletools(.).relationships) < 500
any of
file.oletools(.).relationshipswhere any holds:all of:
any of
ml.nlu_classifier(ml.link_analysis(.target_url).final_dom.display_text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
- .target_url.domain.root_domain not in ('google.com', 'goo.gl')
- ml.link_analysis(.target_url).effective_url.domain.domain is not 'login.microsoftonline.com'
- ml.link_analysis(.target_url).credphish.disposition is 'phishing'
any of:
all of:
- profile.by_sender().prevalence in ('new', 'outlier')
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.oletools, ml.link_analysis, ml.nlu_classifier, profile.by_sender. Reference lists: $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
ml.nlu_classifier(ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).final_dom.display_text).intents[].name | equals | cred_theft |
ml.nlu_classifier(ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).final_dom.display_text).intents[].confidence | member | medium |
ml.nlu_classifier(ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).final_dom.display_text).intents[].confidence | member | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.oletools(attachments).relationships)
or
and
any(ml.nlu_classifier(ml.link_analysis(file.oletools(attachments).relationships.target_url).final_dom.display_text).intents)
and
ml.nlu_classifier(ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).final_dom.display_text).intents[].confidence in ["high", "medium"]
ml.nlu_classifier(ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).final_dom.display_text).intents[].name eq "cred_theft"
not
file.oletools(attachments[]).relationships[].target_url.domain.root_domain in ["goo.gl", "google.com"]
ml.link_analysis func_call "ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).effective_url.domain.domain != login.microsoftonline.com"
ml.link_analysis func_call "ml.link_analysis(file.oletools(attachments[]).relationships[].target_url).credphish.disposition == phishing"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
file.oletools(attachments[]).relationships length_compare "500"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office file with credential phishing URLs
#Detects Office documents containing embedded URLs that redirect to credential phishing pages. The rule filters out standard XML namespace and schema URLs commonly found in legitimate Office documents, then analyzes remaining URLs for malicious content using machine learning link analysis.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// Filter to Office documents that contain 1-3 non-schema URLs
and any(filter(attachments,
// Only check Office documents that can contain macros/embedded content
.file_extension in $file_extensions_macros
// Count URLs after filtering out common XML namespace/schema URLs
and 0 < sum(map(map(file.explode(.),
// Filter out standard XML namespace URLs that appear in all Office docs
filter(.scan.url.urls,
// Exclude OpenXML format schemas
.domain.domain not in (
'schemas.openxmlformats.org',
'schemas.microsoft.com',
'www.w3.org'
)
// Additional Microsoft domain exclusion
and not .domain.domain in (
'microsoft.com',
'wps.cn' // WPS is a china based alt to MS Office and used in namespaces of the documents created by that product
)
// Exclude Dublin Core persistent URLs (metadata schemas)
and not (
.domain.domain == 'purl.org'
and strings.starts_with(.path,
'/dc/'
)
)
// Exclude Dublin Core XML schemas
and not (
.domain.domain == "dublincore.org"
and strings.starts_with(.path,
'/schemas/xmls/'
)
)
)
),
// Count URLs in each exploded file component
length(.)
)
) <= 3 // Only process attachments with 3 or fewer non-schema URLs
),
// For the filtered Office documents, check for malicious URLs
any(file.explode(.),
any(
// Apply the same URL filtering to remove XML namespace noise
filter(.scan.url.urls,
.domain.domain not in (
'schemas.openxmlformats.org',
'schemas.microsoft.com',
'www.w3.org'
)
and not .domain.domain in (
'microsoft.com',
'wps.cn' // WPS is a china based alt to MS Office and used in namespaces of the documents created by that product
)
and not (
.domain.domain == 'purl.org'
and strings.starts_with(.path, '/dc/')
)
and not (
.domain.domain == "dublincore.org"
and strings.starts_with(.path, '/schemas/xmls/')
)
),
// Run link analysis on the filtered URLs to detect phishing
ml.link_analysis(.).credphish.disposition == "phishing"
// confidence is only returned when brands, if it's not there, consider this true
// this ensures if there is a brand, the confidence is high
// and allows matching when there is no confidence
and coalesce(ml.link_analysis(.).credphish.confidence == "high",
true
)
and not (
ml.link_analysis(.).credphish.brand.name is not null
and ml.link_analysis(.).credphish.brand.name == "GoDaddy"
and strings.icontains(ml.link_analysis(.).final_dom.inner_text,
'is parked free, courtesy of GoDaddy.com.'
)
and strings.icontains(ml.link_analysis(.).final_dom.inner_text,
'Get This Domain'
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects Office documents containing embedded URLs that redirect to credential phishing pages. The rule filters out standard XML namespace and schema URLs commonly found in legitimate Office documents, then analyzes remaining URLs for malicious content using machine learning link analysis.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
filter(.scan.url.urls)where all hold:- ml.link_analysis(.).credphish.disposition is 'phishing'
- coalesce(ml.link_analysis(.).credphish.confidence == 'high')
not:
all of:
- ml.link_analysis(.).credphish.brand.name is set
- ml.link_analysis(.).credphish.brand.name is 'GoDaddy'
- ml.link_analysis(.).final_dom.inner_text contains 'is parked free, courtesy of GoDaddy.com.'
- ml.link_analysis(.).final_dom.inner_text contains 'Get This Domain'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, ml.link_analysis, strings.icontains, strings.starts_with. Reference lists: $file_extensions_macros.
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(filter(file.explode(filter(attachments)).scan.url.urls))
and
not
and
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).credphish.brand.name == GoDaddy"
ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).credphish.brand.name is_not_null
ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).final_dom.inner_text contains "Get This Domain"
ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).final_dom.inner_text contains "is parked free, courtesy of GoDaddy.com."
coalesce func_call "coalesce(ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).credphish.confidence == 'high')"
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(filter(attachments)[])[].scan.url.urls)[]).credphish.disposition == phishing"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office file with document sharing and browser instruction lures
#Detects macro-enabled attachments containing document sharing language (sent, shared, forwarded) combined with browser interaction instructions (copy, right-click) or common email disclaimers. These tactics are often used to trick users into enabling macros or following malicious instructions.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments,
.file_extension in $file_extensions_macros
// limit the size to reduce FPs, the larger the document, the more likely it is for FPs on benign automated reports
and .size < 2000000
),
// Detection Note: There are multiple regex patterns used in multiple places, it'll be important to keep them in sync
any(file.explode(.),
// document sharing lure
(
length(.scan.strings.raw, ) < 1000
and regex.icontains(.scan.strings.raw,
'(?:sent|shared|forwarded|provided|invited|received)(?:\s+\w+){0,9}\s+(?:document|file|attachment)',
)
)
// ocr output
or (
length(.scan.ocr.raw) < 1000
and regex.icontains(.scan.ocr.raw,
'(?:sent|shared|forwarded|provided|invited|received)(?:\s+\w+){0,9}\s+(?:document|file|attachment)',
)
)
or (
length(.scan.ocr.raw) < 500
and strings.ends_with(.scan.ocr.raw, 'REVIEW DOCUMENTS')
)
)
// copy/paste stuff or disclaimer text in the OCR output
and (
any(file.explode(.),
(
length(.scan.strings.raw, ) < 1000
and (
regex.icontains(.scan.strings.raw,
'(?:copy (?:and paste)?|right.?click)(?:\s+\w+\s*){0,9}browser',
'click.{0,50}(?:above|below|button) to (?:access|open)'
)
)
)
// ocr output
or (
length(.scan.ocr.raw) < 1000
and (
regex.icontains(.scan.ocr.raw,
'(?:copy (?:and paste)?|right.?click)(?:\s+\w+\s*){0,9}browser',
'click.{0,50}(?:above|below|button) to (?:access|open)'
)
)
)
or 5 of (
strings.icontains(.scan.ocr.raw,
'confidential and intended solely'
),
strings.icontains(.scan.ocr.raw,
'intended solely for the use of'
),
strings.icontains(.scan.ocr.raw, 'intended only for the people'),
strings.icontains(.scan.ocr.raw, 'intended recipient'),
strings.icontains(.scan.ocr.raw, 'received this email in error'),
strings.icontains(.scan.ocr.raw,
'notify the sender immediately'
),
strings.icontains(.scan.ocr.raw, 'delete it from your system'),
strings.icontains(.scan.ocr.raw, 'delete the email from'),
strings.icontains(.scan.ocr.raw, 'virus-free'),
strings.icontains(.scan.ocr.raw, 'scan for viruses'),
strings.icontains(.scan.ocr.raw, 'legally binding agreement'),
strings.icontains(.scan.ocr.raw, 'informational purposes only'),
strings.icontains(.scan.ocr.raw,
'any attachments are confidential'
),
strings.icontains(.scan.ocr.raw, 'loss or damage arising'),
strings.icontains(.scan.ocr.raw, 'responsibility for any loss'),
strings.icontains(.scan.ocr.raw, 'unauthorised and prohibited'),
strings.icontains(.scan.ocr.raw, 'subject to legal privilege'),
strings.icontains(.scan.ocr.raw,
'The information contained in or attached'
),
strings.icontains(.scan.ocr.raw,
'The information contained in this email'
),
strings.icontains(.scan.ocr.raw,
'people to whom it is addressed'
),
strings.icontains(.scan.ocr.raw,
'received this in error, please inform'
),
strings.icontains(.scan.ocr.raw, 'inform the sender and/or'),
strings.icontains(.scan.ocr.raw,
'immediately and delete the material'
),
strings.icontains(.scan.ocr.raw,
'then delete the email from your inbox'
),
strings.icontains(.scan.ocr.raw,
'confidential and/or privileged material'
),
strings.icontains(.scan.ocr.raw,
'confidential and / or legally privileged'
),
strings.icontains(.scan.ocr.raw,
'The information transmitted is intended'
),
strings.icontains(.scan.ocr.raw,
'other than the intended recipient is prohibited'
),
strings.icontains(.scan.ocr.raw,
'intended for use by the addressee'
),
strings.icontains(.scan.ocr.raw,
'taking of any action in reliance upon'
),
strings.icontains(.scan.ocr.raw,
'distribution is strictly prohibited'
),
strings.icontains(.scan.ocr.raw,
'communication from the sender is confidential'
),
strings.icontains(.scan.ocr.raw, 'use by the recipient'),
strings.icontains(.scan.ocr.raw,
'and others authorized to receive it'
),
strings.icontains(.scan.ocr.raw, 'you are hereby notified'),
strings.icontains(.scan.ocr.raw,
'action in relation of the contents of this information'
),
strings.icontains(.scan.ocr.raw,
'The information contained in this'
),
strings.icontains(.scan.ocr.raw, 'you are not the recipient'),
strings.icontains(.scan.ocr.raw, 'may be unlawful'),
)
)
)
)
Detection logic
Scope: inbound message.
Detects macro-enabled attachments containing document sharing language (sent, shared, forwarded) combined with browser interaction instructions (copy, right-click) or common email disclaimers. These tactics are often used to trick users into enabling macros or following malicious instructions.
- inbound message
any of
filter(attachments)where all hold:any of
file.explode(.)where any holds:all of:
- length(.scan.strings.raw) < 1000
- .scan.strings.raw matches '(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)'
all of:
- length(.scan.ocr.raw) < 1000
- .scan.ocr.raw matches '(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)'
all of:
- length(.scan.ocr.raw) < 500
- .scan.ocr.raw ends with 'REVIEW DOCUMENTS'
any of
file.explode(.)where any holds:all of:
- length(.scan.strings.raw) < 1000
.scan.strings.raw matches any of 2 patterns
(?:copy (?:and paste)?|right.?click)(?:\s+\w+\s*){0,9}browserclick.{0,50}(?:above|below|button) to (?:access|open)
all of:
- length(.scan.ocr.raw) < 1000
.scan.ocr.raw matches any of 2 patterns
(?:copy (?:and paste)?|right.?click)(?:\s+\w+\s*){0,9}browserclick.{0,50}(?:above|below|button) to (?:access|open)
at least 5 of 39: .scan.ocr.raw contains any of 39 patterns
confidential and intended solelyintended solely for the use ofintended only for the peopleintended recipientreceived this email in errornotify the sender immediatelydelete it from your systemdelete the email fromvirus-freescan for viruseslegally binding agreementinformational purposes onlyany attachments are confidentialloss or damage arisingresponsibility for any lossunauthorised and prohibitedsubject to legal privilegeThe information contained in or attachedThe information contained in this emailpeople to whom it is addressedreceived this in error, please informinform the sender and/orimmediately and delete the materialthen delete the email from your inboxconfidential and/or privileged materialconfidential and / or legally privilegedThe information transmitted is intendedother than the intended recipient is prohibitedintended for use by the addresseetaking of any action in reliance upondistribution is strictly prohibitedcommunication from the sender is confidentialuse by the recipientand others authorized to receive ityou are hereby notifiedaction in relation of the contents of this informationThe information contained in thisyou are not the recipientmay be unlawful
Inspects: attachments[].file_extension, attachments[].size, type.inbound. Sensors: file.explode, regex.icontains, strings.ends_with, strings.icontains. Reference lists: $file_extensions_macros.
Indicators matched (43)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (?:sent|shared|forwarded|provided|invited|received)(?:\s+\w+){0,9}\s+(?:document|file|attachment) |
strings.ends_with | suffix | REVIEW DOCUMENTS |
regex.icontains | regex | (?:copy (?:and paste)?|right.?click)(?:\s+\w+\s*){0,9}browser |
regex.icontains | regex | click.{0,50}(?:above|below|button) to (?:access|open) |
strings.icontains | substring | confidential and intended solely |
strings.icontains | substring | intended solely for the use of |
strings.icontains | substring | intended only for the people |
strings.icontains | substring | intended recipient |
strings.icontains | substring | received this email in error |
strings.icontains | substring | notify the sender immediately |
strings.icontains | substring | delete it from your system |
strings.icontains | substring | delete the email from |
31 more
strings.icontains | substring | virus-free |
strings.icontains | substring | scan for viruses |
strings.icontains | substring | legally binding agreement |
strings.icontains | substring | informational purposes only |
strings.icontains | substring | any attachments are confidential |
strings.icontains | substring | loss or damage arising |
strings.icontains | substring | responsibility for any loss |
strings.icontains | substring | unauthorised and prohibited |
strings.icontains | substring | subject to legal privilege |
strings.icontains | substring | The information contained in or attached |
strings.icontains | substring | The information contained in this email |
strings.icontains | substring | people to whom it is addressed |
strings.icontains | substring | received this in error, please inform |
strings.icontains | substring | inform the sender and/or |
strings.icontains | substring | immediately and delete the material |
strings.icontains | substring | then delete the email from your inbox |
strings.icontains | substring | confidential and/or privileged material |
strings.icontains | substring | confidential and / or legally privileged |
strings.icontains | substring | The information transmitted is intended |
strings.icontains | substring | other than the intended recipient is prohibited |
strings.icontains | substring | intended for use by the addressee |
strings.icontains | substring | taking of any action in reliance upon |
strings.icontains | substring | distribution is strictly prohibited |
strings.icontains | substring | communication from the sender is confidential |
strings.icontains | substring | use by the recipient |
strings.icontains | substring | and others authorized to receive it |
strings.icontains | substring | you are hereby notified |
strings.icontains | substring | action in relation of the contents of this information |
strings.icontains | substring | The information contained in this |
strings.icontains | substring | you are not the recipient |
strings.icontains | substring | may be unlawful |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(file.explode(filter(attachments)))
or
and
or
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "(?:copy (?:and paste)?|right.?click)(?:\\s+\\w+\\s*){0,9}browser"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "click.{0,50}(?:above|below|button) to (?:access|open)"
file.explode(filter(attachments)[])[].scan.ocr.raw length_compare "1000"
and
or
file.explode(filter(attachments)[])[].scan.strings.raw regex_match "(?:copy (?:and paste)?|right.?click)(?:\\s+\\w+\\s*){0,9}browser"
file.explode(filter(attachments)[])[].scan.strings.raw regex_match "click.{0,50}(?:above|below|button) to (?:access|open)"
file.explode(filter(attachments)[])[].scan.strings.raw length_compare "1000"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "The information contained in or attached"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "The information contained in this email"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "The information contained in this"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "The information transmitted is intended"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "action in relation of the contents of this information"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "and others authorized to receive it"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "any attachments are confidential"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "communication from the sender is confidential"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "confidential and / or legally privileged"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "confidential and intended solely"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "confidential and/or privileged material"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "delete it from your system"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "delete the email from"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "distribution is strictly prohibited"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "immediately and delete the material"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "inform the sender and/or"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "informational purposes only"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "intended for use by the addressee"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "intended only for the people"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "intended recipient"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "intended solely for the use of"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "legally binding agreement"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "loss or damage arising"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "may be unlawful"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "notify the sender immediately"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "other than the intended recipient is prohibited"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "people to whom it is addressed"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "received this email in error"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "received this in error, please inform"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "responsibility for any loss"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "scan for viruses"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "subject to legal privilege"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "taking of any action in reliance upon"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "then delete the email from your inbox"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "unauthorised and prohibited"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "use by the recipient"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "virus-free"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "you are hereby notified"
file.explode(filter(attachments)[])[].scan.ocr.raw contains "you are not the recipient"
any(file.explode(filter(attachments)))
or
and
file.explode(filter(attachments)[])[].scan.ocr.raw ends_with "REVIEW DOCUMENTS"
file.explode(filter(attachments)[])[].scan.ocr.raw length_compare "500"
and
file.explode(filter(attachments)[])[].scan.ocr.raw length_compare "1000"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)"
and
file.explode(filter(attachments)[])[].scan.strings.raw length_compare "1000"
file.explode(filter(attachments)[])[].scan.strings.raw regex_match "(?:sent|shared|forwarded|provided|invited|received)(?:\\s+\\w+){0,9}\\s+(?:document|file|attachment)"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Office file with suspicious function calls or downloaded file path
#Attached Office file contains suspicious function calls or known malicious file path pattern.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
// office files
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000
)
)
and (
any(file.explode(.),
(
any(.scan.strings.strings,
strings.ilike(., '*URLDownloadToFile*')
)
and any(.scan.strings.strings, strings.ilike(., '*Auto_Open*'))
)
or any(.scan.strings.strings,
regex.icontains(.,
'C:\\[A-Za-z]{7}\\[A-Za-z]{7}\\[A-Za-z]{7}'
)
)
)
)
)
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.
Attached Office file contains suspicious function calls or known malicious file path pattern.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000
any of
file.explode(.)where any holds:all of:
any of
.scan.strings.stringswhere:- . matches '*URLDownloadToFile*'
any of
.scan.strings.stringswhere:- . matches '*Auto_Open*'
any of
.scan.strings.stringswhere:- . matches 'C:\\\\[A-Za-z]{7}\\\\[A-Za-z]{7}\\\\[A-Za-z]{7}'
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
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, profile.by_sender, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *URLDownloadToFile* |
strings.ilike | substring | *Auto_Open* |
regex.icontains | regex | C:\\[A-Za-z]{7}\\[A-Za-z]{7}\\[A-Za-z]{7} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Auto_Open"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "URLDownloadToFile"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "C:\\\\[A-Za-z]{7}\\\\[A-Za-z]{7}\\\\[A-Za-z]{7}"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: OLE external relationship containing file scheme link to executable filetype
#This rule identifies attachments containing file scheme links pointing to executable file types, a common indicator of malware distribution. It applies to various suspicious file extensions and archive formats, aiming to prevent the initiation and execution of malicious software.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and length(file.oletools(.).relationships) < 500
and any(file.oletools(.).relationships,
.target_url.scheme == "file"
and regex.icontains(.target_url.path,
'\.(action|ahk|apk|app|appimage|applescript|bat|bin|cab|cmd|command|cpl|dll|dmg|exe|gadget|hta|inf|ins|ipa|isu|jar|job|js|jse|lnk|msi|msp|paf|pif|ps1|rgs|run|scr|sct|sh|shb|vb|vbe|vbs)($|[^\w])'
)
// avoid flagging on internal/network drives mappings
and not (
strings.starts_with(.target_url.scheme, "file")
and not regex.imatch(.target_url.path, '/?[a-z]:/')
)
)
)
and (
not profile.by_sender().any_messages_benign
or profile.by_sender().any_messages_malicious_or_spam
)
Detection logic
Scope: inbound message.
This rule identifies attachments containing file scheme links pointing to executable file types, a common indicator of malware distribution. It applies to various suspicious file extensions and archive formats, aiming to prevent the initiation and execution of malicious software.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- length(file.oletools(.).relationships) < 500
any of
file.oletools(.).relationshipswhere all hold:- .target_url.scheme is 'file'
- .target_url.path matches '\\.(action|ahk|apk|app|appimage|applescript|bat|bin|cab|cmd|command|cpl|dll|dmg|exe|gadget|hta|inf|ins|ipa|isu|jar|job|js|jse|lnk|msi|msp|paf|pif|ps1|rgs|run|scr|sct|sh|shb|vb|vbe|vbs)($|[^\\w])'
not:
all of:
- .target_url.scheme starts with 'file'
not:
- .target_url.path matches '/?[a-z]:/'
any of:
not:
- profile.by_sender().any_messages_benign
- profile.by_sender().any_messages_malicious_or_spam
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.oletools, profile.by_sender, regex.icontains, regex.imatch, strings.starts_with. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.oletools(attachments[]).relationships[].target_url.scheme | equals | file |
regex.icontains | regex | \.(action|ahk|apk|app|appimage|applescript|bat|bin|cab|cmd|command|cpl|dll|dmg|exe|gadget|hta|inf|ins|ipa|isu|jar|job|js|jse|lnk|msi|msp|paf|pif|ps1|rgs|run|scr|sct|sh|shb|vb|vbe|vbs)($|[^\w]) |
regex.imatch | regex | /?[a-z]:/ |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.oletools(attachments).relationships)
and
not
and
not
file.oletools(attachments[]).relationships[].target_url.path regex_match "/?[a-z]:/"
file.oletools(attachments[]).relationships[].target_url.scheme starts_with "file"
file.oletools(attachments[]).relationships[].target_url.path regex_match "\\.(action|ahk|apk|app|appimage|applescript|bat|bin|cab|cmd|command|cpl|dll|dmg|exe|gadget|hta|inf|ins|ipa|isu|jar|job|js|jse|lnk|msi|msp|paf|pif|ps1|rgs|run|scr|sct|sh|shb|vb|vbe|vbs)($|[^\\w])"
file.oletools(attachments[]).relationships[].target_url.scheme eq "file"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
file.oletools(attachments[]).relationships length_compare "500"
or
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: OLE external relationship containing file scheme link to IP address
#This rule identifies attachments containing file scheme links pointing to IP Addresses, a common indicator of malware distribution. It applies to various suspicious file extensions and archive formats, aiming to prevent the initiation and execution of malicious software. The rule negates firing on IP addresses governed by RFC1918 or privately allocated space.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or .file_extension in~ $file_extensions_common_archives
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.oletools(.).relationships,
.target_url.scheme == "file"
and regex.contains(.target_url.path,
'([0-9]{2,3}\.){3}[0-9]{2,3}'
)
and not regex.icontains(.target_url.path,
'(10\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]))|(172\.(?:1[6-9]|2\d|3[0-1])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]))|(192\.168\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]))'
)
)
)
and (
not profile.by_sender().any_messages_benign
or profile.by_sender().any_messages_malicious_or_spam
)
Detection logic
Scope: inbound message.
This rule identifies attachments containing file scheme links pointing to IP Addresses, a common indicator of malware distribution. It applies to various suspicious file extensions and archive formats, aiming to prevent the initiation and execution of malicious software. The rule negates firing on IP addresses governed by RFC1918 or privately allocated space.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension in $file_extensions_common_archives
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.oletools(.).relationshipswhere all hold:- .target_url.scheme is 'file'
- .target_url.path matches '([0-9]{2,3}\\.){3}[0-9]{2,3}'
not:
- .target_url.path matches '(10\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))|(172\\.(?:1[6-9]|2\\d|3[0-1])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))|(192\\.168\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))'
any of:
not:
- profile.by_sender().any_messages_benign
- profile.by_sender().any_messages_malicious_or_spam
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.oletools, profile.by_sender, regex.contains, regex.icontains. Reference lists: $file_extensions_common_archives, $file_extensions_macros.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
file.oletools(attachments[]).relationships[].target_url.scheme | equals | file |
regex.contains | regex | ([0-9]{2,3}\.){3}[0-9]{2,3} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.oletools(attachments).relationships)
and
not
file.oletools(attachments[]).relationships[].target_url.path regex_match "(10\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))|(172\\.(?:1[6-9]|2\\d|3[0-1])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))|(192\\.168\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))"
file.oletools(attachments[]).relationships[].target_url.path regex_match "([0-9]{2,3}\\.){3}[0-9]{2,3}"
file.oletools(attachments[]).relationships[].target_url.scheme eq "file"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_common_archives"
macro "attachments[].file_extension in file_extensions_macros"
or
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Password-protected PDF with fake document indicators
#Detects PDF attachments that are password protected and matching YARA signatures looking for specific content observed in previous activity.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Encryption, Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and any(filter(attachments, .file_type == "pdf"),
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta featuer in custom rules is not suggested until it has been formally released.
//
any(beta.parse_exif(.).fields,
strings.icontains(.value, 'password protected')
)
and any(file.explode(.),
any(.scan.yara.matches,
.name in ("pwd_protected_pdf_fake_document_1")
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments that are password protected and matching YARA signatures looking for specific content observed in previous activity.
- inbound message
- length(attachments) is 1
any of
filter(attachments)where all hold:any of
beta.parse_exif(.).fieldswhere:- .value contains 'password protected'
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pwd_protected_pdf_fake_document_1')
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode, strings.icontains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | password protected |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pwd_protected_pdf_fake_document_1 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pwd_protected_pdf_fake_document_1"
any(beta.parse_exif(filter(attachments)).fields)
beta.parse_exif(filter(attachments)).fields.value contains "password protected"
attachments length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF Attachment with links to workers.dev
#Detects inbound messages containing PDF attachments with fewer than 5 pages that, when analyzed, contain URLs pointing to workers.dev subdomains. This pattern indicates potential abuse of Cloudflare Workers infrastructure to host malicious content delivered via PDF documents.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Free subdomain host, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
beta.parse_exif(.).page_count <= 2
and any(file.explode(.),
any(.scan.url.urls, .domain.root_domain == "workers.dev")
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing PDF attachments with fewer than 5 pages that, when analyzed, contain URLs pointing to workers.dev subdomains. This pattern indicates potential abuse of Cloudflare Workers infrastructure to host malicious content delivered via PDF documents.
- inbound message
any of
filter(attachments)where all hold:- beta.parse_exif(.).page_count ≤ 2
any of
file.explode(.)where:any of
.scan.url.urlswhere:- .domain.root_domain is 'workers.dev'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.url.urls[].domain.root_domain | equals | workers.dev |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.url.urls)
file.explode(filter(attachments)).scan.url.urls.domain.root_domain eq "workers.dev"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).page_count <= 2"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF bid/proposal lure with credential theft indicators
#Detects single-page PDF attachments containing bid, proposal, RFP, RFQ, or quotation-related lures combined with high-confidence credential theft language or suspicious domains. The rule examines various locations including PDF URLs, OCR content, file names, subject lines, and message body for these indicators.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Free file host, Free subdomain host |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// only one attachment
and length(attachments) == 1
// only pdfs with one page
//
// 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(attachments, .file_type == 'pdf' and beta.parse_exif(.).page_count == 1)
// two of these...
and 2 of (
// bid/rfp/proposal phrases commonly observed in lures which are in the display text of a url from the pdf
any(attachments,
any(file.explode(.),
any(.scan.url.urls,
regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
'(?:\b(?:request|review)\b.{1,5}\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b)'
)
)
)
),
(
// bid/rfp/proposal phrases commonly observed in lures which are in various spots in the message
any([subject.base, sender.display_name, body.current_thread.text],
regex.icontains(., '\b(?:bid|proposal|rfp|rfq|quotation)\b')
)
),
// bid/rfp/proposal phrases commonly observed in lures which are in the file name
any(attachments,
regex.icontains(.file_name, '\b(?:bid|proposal|rfp|rfq|quotation)\b')
),
any(attachments,
any(file.explode(.),
// bid/rfp/proposal phrases commonly observed in lures which are in the ocr of the pdf
regex.icontains(.scan.ocr.raw,
'(?:\b(?:request|review)\b.{1,5}\\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b)'
)
)
),
(
any(attachments,
any(file.explode(.),
any(.scan.url.urls,
// bid/rfp/proposal phrases commonly observed in lures which are in the url
regex.icontains(.url,
'(?:bid|proposal|agreement|contract|settlement|RFQ|RFP|quotation)'
)
)
)
)
)
)
// ocr indicates high confidence cred theft
and (
any(attachments,
any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == 'cred_theft' and .confidence == 'high'
)
or any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name == 'Purchase Orders' and .confidence == 'high'
)
)
)
// message body current thread indicates high confidence cred theft
or any(ml.nlu_classifier(body.current_thread.text).intents,
.name == 'cred_theft' and .confidence == 'high'
)
// message body current thread indicates high confidence cred theft
or any(ml.nlu_classifier(body.current_thread.text).topics,
.name == 'Purchase Orders' and .confidence == 'high'
)
)
// pdf contains some suspicious url domain
and (
any(attachments,
any(file.explode(.),
any(.scan.url.urls,
.domain.root_domain in $self_service_creation_platform_domains
or .domain.domain in $self_service_creation_platform_domains
or .domain.root_domain in $free_file_hosts
or .domain.domain in $free_file_hosts
or .domain.root_domain in $free_subdomain_hosts
or .domain.domain in $free_subdomain_hosts
or .domain.tld in $suspicious_tlds
or .domain.domain in $url_shorteners
or .domain.root_domain in $url_shorteners
)
)
)
)
// we dont want emails where all the links are docusign or dotloop
and not all(body.links,
.href_url.domain.root_domain in (
'docusign.net',
'docusign.com',
'dotloop.com'
)
)
// negating solicited senders is necessary due to the nature of the rule
and not profile.by_sender().solicited
// negate workflow robot
and not (
sender.email.local_part == 'workflow.robot'
and sender.email.domain.root_domain == 'effem.com'
)
Detection logic
Scope: inbound message.
Detects single-page PDF attachments containing bid, proposal, RFP, RFQ, or quotation-related lures combined with high-confidence credential theft language or suspicious domains. The rule examines various locations including PDF URLs, OCR content, file names, subject lines, and message body for these indicators.
- inbound message
- length(attachments) is 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
- beta.parse_exif(.).page_count is 1
at least 2 of:
any of
attachmentswhere:any of
file.explode(.)where:any of
.scan.url.urlswhere:- ml.link_analysis(., mode='aggressive').final_dom.display_text matches '(?:\\b(?:request|review)\\b.{1,5}\\b(?:bid|proposal|rfp|rfq|quotation)\\b|\\b(?:bid|proposal|rfp|rfq|quotation)\\b.{1,5}\\b(?:request|review)\\b)'
any of
[subject.base, sender.display_name, body.current_thread.text]where:- . matches '\\b(?:bid|proposal|rfp|rfq|quotation)\\b'
any of
attachmentswhere:- .file_name matches '\\b(?:bid|proposal|rfp|rfq|quotation)\\b'
any of
attachmentswhere:any of
file.explode(.)where:- .scan.ocr.raw matches '(?:\\b(?:request|review)\\b.{1,5}\\\\b(?:bid|proposal|rfp|rfq|quotation)\\b|\\b(?:bid|proposal|rfp|rfq|quotation)\\b.{1,5}\\b(?:request|review)\\b)'
any of
attachmentswhere:any of
file.explode(.)where:any of
.scan.url.urlswhere:- .url matches '(?:bid|proposal|agreement|contract|settlement|RFQ|RFP|quotation)'
any of:
any of
attachmentswhere:any of
file.explode(.)where any holds:any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere all hold:- .name is 'Purchase Orders'
- .confidence is 'high'
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name is 'Purchase Orders'
- .confidence is 'high'
any of
attachmentswhere:any of
file.explode(.)where:any of
.scan.url.urlswhere any holds:- .domain.root_domain in $self_service_creation_platform_domains
- .domain.domain in $self_service_creation_platform_domains
- .domain.root_domain in $free_file_hosts
- .domain.domain in $free_file_hosts
- .domain.root_domain in $free_subdomain_hosts
- .domain.domain in $free_subdomain_hosts
- .domain.tld in $suspicious_tlds
- .domain.domain in $url_shorteners
- .domain.root_domain in $url_shorteners
not:
all of
body.linkswhere:- .href_url.domain.root_domain in ('docusign.net', 'docusign.com', 'dotloop.com')
not:
- profile.by_sender().solicited
not:
all of:
- sender.email.local_part is 'workflow.robot'
- sender.email.domain.root_domain is 'effem.com'
Inspects: attachments[].file_name, attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, sender.display_name, sender.email.domain.root_domain, sender.email.local_part, subject.base, type.inbound. Sensors: beta.parse_exif, file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender, regex.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $self_service_creation_platform_domains, $suspicious_tlds, $url_shorteners.
Indicators matched (13)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | (?:\b(?:request|review)\b.{1,5}\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b) |
regex.icontains | regex | \b(?:bid|proposal|rfp|rfq|quotation)\b |
regex.icontains | regex | (?:\b(?:request|review)\b.{1,5}\\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b) |
regex.icontains | regex | (?:bid|proposal|agreement|contract|settlement|RFQ|RFP|quotation) |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name | equals | Purchase Orders |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence | equals | high |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | equals | high |
ml.nlu_classifier(body.current_thread.text).topics[].name | equals | Purchase Orders |
1 more
ml.nlu_classifier(body.current_thread.text).topics[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
any(file.explode(attachments))
or
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"
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).topics)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidence eq "high"
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].name eq "Purchase Orders"
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 eq "Purchase Orders"
or
any(attachments)
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
file.explode(attachments).scan.url.urls.url regex_match "(?:bid|proposal|agreement|contract|settlement|RFQ|RFP|quotation)"
any(attachments)
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.display_text regex_match "(?:\\b(?:request|review)\\b.{1,5}\\b(?:bid|proposal|rfp|rfq|quotation)\\b|\\b(?:bid|proposal|rfp|rfq|quotation)\\b.{1,5}\\b(?:request|review)\\b)"
any(attachments)
any(file.explode(attachments))
file.explode(attachments).scan.ocr.raw regex_match "(?:\\b(?:request|review)\\b.{1,5}\\\\b(?:bid|proposal|rfp|rfq|quotation)\\b|\\b(?:bid|proposal|rfp|rfq|quotation)\\b.{1,5}\\b(?:request|review)\\b)"
any([subject.base, sender.display_name, body.current_thread.text])
[subject.base, sender.display_name, body.current_thread.text] regex_match "\\b(?:bid|proposal|rfp|rfq|quotation)\\b"
any(attachments)
attachments.file_name regex_match "\\b(?:bid|proposal|rfp|rfq|quotation)\\b"
any(attachments)
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
or
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain in free_file_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain in free_subdomain_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain in self_service_creation_platform_domains"
macro "file.explode(attachments[])[].scan.url.urls[].domain.domain in url_shorteners"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_file_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in self_service_creation_platform_domains"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in url_shorteners"
macro "file.explode(attachments[])[].scan.url.urls[].domain.tld in suspicious_tlds"
any(attachments)
and
attachments.file_type eq "pdf"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
not
and
sender.email.domain.root_domain eq "effem.com"
sender.email.local_part eq "workflow.robot"
not
profile.by_sender func_call "profile.by_sender().solicited"
not
macro "all(body.links)"
attachments length_compare "1"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | eq | effem.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"effem.com" |
sender.email.local_part | eq | workflow.robot | excludes:sender.email.local_part field:"sender.email.local_part" value:"workflow.robot" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF contains W9 or invoice YARA signatures
#PDF attachment contains YARA signatures commonly associated with fraudulent W9 tax forms or invoice documents, which are frequently used in social engineering attacks to steal sensitive information or facilitate business email compromise.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name in ("w9_pdf_01", "invoice_pdf_01", "w9_pdf_IDs")
)
)
)
Detection logic
Scope: inbound message.
PDF attachment contains YARA signatures commonly associated with fraudulent W9 tax forms or invoice documents, which are frequently used in social engineering attacks to steal sensitive information or facilitate business email compromise.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('w9_pdf_01', 'invoice_pdf_01', 'w9_pdf_IDs')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | w9_pdf_01 |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | invoice_pdf_01 |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | w9_pdf_IDs |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name in ["invoice_pdf_01", "w9_pdf_01", "w9_pdf_IDs"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF file with link to fake Bitcoin exchange
#Fraudulent message containing a PDF notification of unclaimed Bitcoin assets. The PDF file contains a link to a fake Cryptocurrency portal. Attempting to withdraw funds prompts the user to enter payment information.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Free email provider, Impersonation: Brand, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and sender.email.domain.root_domain in $free_email_providers
and length(attachments) == 1
and all(attachments,
.file_extension == "pdf"
and regex.icontains(.file_name, '(\d\.\d{3,4}.{0,12}BTC|bitcoin)')
and any(file.explode(.),
.scan.exiftool.page_count >= 5
and .depth == 0
and length(filter(.scan.strings.strings,
regex.match(., '^\/URI \(http.*')
)
) == 1
)
)
Detection logic
Scope: inbound message.
Fraudulent message containing a PDF notification of unclaimed Bitcoin assets. The PDF file contains a link to a fake Cryptocurrency portal. Attempting to withdraw funds prompts the user to enter payment information.
- inbound message
- sender.email.domain.root_domain in $free_email_providers
- length(attachments) is 1
all of
attachmentswhere all hold:- .file_extension is 'pdf'
- .file_name matches '(\\d\\.\\d{3,4}.{0,12}BTC|bitcoin)'
any of
file.explode(.)where all hold:- .scan.exiftool.page_count ≥ 5
- .depth is 0
- length(filter(.scan.strings.strings, regex.match(., '^\\/URI \\(http.*'))) is 1
Inspects: attachments[].file_extension, attachments[].file_name, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, regex.icontains, regex.match. Reference lists: $free_email_providers.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
regex.icontains | regex | (\d\.\d{3,4}.{0,12}BTC|bitcoin) |
regex.match | regex | ^\/URI \(http.* |
Stages and Predicates
Stage 1: mql_rule
and
attachments length_compare "1"
type.inbound eq "true"
macro "all(attachments)"
macro "sender.email.domain.root_domain in free_email_providers"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF file with low reputation link to ZIP file (unsolicited)
#Detects messages with PDF attachments linking directly to zip files from unsolicited senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request"
)
and any(attachments,
.file_extension == "pdf"
and any(file.explode(.),
any(.scan.pdf.urls,
regex.contains(.url, '\.(?:zip)')
and .domain.root_domain not in $tranco_1m
)
)
)
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.
Detects messages with PDF attachments linking directly to zip files from unsolicited senders.
- inbound message
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name is 'request'
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where:any of
.scan.pdf.urlswhere all hold:- .url matches '\\.(?:zip)'
- .domain.root_domain not in $tranco_1m
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: attachments[].file_extension, body.current_thread.text, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender, regex.contains. Reference lists: $tranco_1m.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
attachments[].file_extension | equals | pdf |
regex.contains | regex | \.(?:zip) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.pdf.urls)
and
file.explode(attachments[])[].scan.pdf.urls[].url regex_match "\\.(?:zip)"
macro "file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain not in tranco_1m"
attachments.file_extension eq "pdf"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
any(ml.nlu_classifier(body.current_thread.text).entities)
ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF file with low reputation links to suspicious filetypes (unsolicited)
#Detects messages with PDF attachments linking directly to suspicious filetypes on hosts with low reputation from unsolicited senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request"
)
and any(attachments,
.file_extension == "pdf"
and any(file.explode(.),
any(.scan.pdf.urls,
regex.contains(.path,
'\.(?:exe|cab|vbs|ps1|rar|iso|dll|one|lnk|sh)\b'
)
and .domain.root_domain not in $tranco_1m
)
)
)
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.
Detects messages with PDF attachments linking directly to suspicious filetypes on hosts with low reputation from unsolicited senders.
- inbound message
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name is 'request'
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where:any of
.scan.pdf.urlswhere all hold:- .path matches '\\.(?:exe|cab|vbs|ps1|rar|iso|dll|one|lnk|sh)\\b'
- .domain.root_domain not in $tranco_1m
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: attachments[].file_extension, body.current_thread.text, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender, regex.contains. Reference lists: $tranco_1m.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
attachments[].file_extension | equals | pdf |
regex.contains | regex | \.(?:exe|cab|vbs|ps1|rar|iso|dll|one|lnk|sh)\b |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.pdf.urls)
and
file.explode(attachments[])[].scan.pdf.urls[].path regex_match "\\.(?:exe|cab|vbs|ps1|rar|iso|dll|one|lnk|sh)\\b"
macro "file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain not in tranco_1m"
attachments.file_extension eq "pdf"
or
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
any(ml.nlu_classifier(body.current_thread.text).entities)
ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF file with recipient domain and ATT eCheckRun pattern
#Detects PDF attachments with filenames containing the recipient's domain, potentially indicating targeted financial document spoofing.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
strings.icontains(.file_name, recipients.to[0].email.domain.sld)
and strings.starts_with(.file_name, "ATT")
and strings.icontains(.file_name, "eCheckRun")
)
Detection logic
Scope: inbound message.
Detects PDF attachments with filenames containing the recipient's domain, potentially indicating targeted financial document spoofing.
- inbound message
any of
filter(attachments)where all hold:- strings.icontains(.file_name)
- .file_name starts with 'ATT'
- .file_name contains 'eCheckRun'
Inspects: attachments[].file_type, recipients.to[0].email.domain.sld, type.inbound. Sensors: strings.icontains, strings.starts_with.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | ATT |
strings.icontains | substring | eCheckRun |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
filter(attachments).file_name contains "eCheckRun"
filter(attachments).file_name starts_with "ATT"
strings.icontains func_call "strings.icontains(filter(attachments)[].file_name)"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF generated with wkhtmltopdf tool and default title
#Detects PDF attachments that were generated using the wkhtmltopdf conversion tool, which converts HTML/CSS to PDF. This tool is commonly used by attackers to create legitimate-looking PDF documents from web content for social engineering purposes.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Callback Phishing, Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_extension == "pdf"),
strings.istarts_with(beta.parse_exif(.).producer, "Qt")
and strings.icontains(beta.parse_exif(.).creator, "wkhtmltopdf")
and beta.parse_exif(.).title == "Document"
)
Detection logic
Scope: inbound message.
Detects PDF attachments that were generated using the wkhtmltopdf conversion tool, which converts HTML/CSS to PDF. This tool is commonly used by attackers to create legitimate-looking PDF documents from web content for social engineering purposes.
- inbound message
any of
filter(attachments)where all hold:- beta.parse_exif(.).producer starts with 'Qt'
- beta.parse_exif(.).creator contains 'wkhtmltopdf'
- beta.parse_exif(.).title is 'Document'
Inspects: attachments[].file_extension, type.inbound. Sensors: beta.parse_exif, strings.icontains, strings.istarts_with.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
strings.istarts_with | prefix | Qt |
strings.icontains | substring | wkhtmltopdf |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).title == Document"
beta.parse_exif(filter(attachments)[]).creator contains "wkhtmltopdf"
beta.parse_exif(filter(attachments)[]).producer starts_with "Qt"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF Object Hash - Encrypted PDFs with fake payment notification
#Detects PDF attachments containing a specific object hash (63bf167b66091a4bc53e8944a76f6b08) that may indicate malicious content or known threat indicators.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.scan.pdf_obj_hash.object_hash == "63bf167b66091a4bc53e8944a76f6b08"
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a specific object hash (63bf167b66091a4bc53e8944a76f6b08) that may indicate malicious content or known threat indicators.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:- .scan.pdf_obj_hash.object_hash is '63bf167b66091a4bc53e8944a76f6b08'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.pdf_obj_hash.object_hash | equals | 63bf167b66091a4bc53e8944a76f6b08 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.pdf_obj_hash.object_hash eq "63bf167b66091a4bc53e8944a76f6b08"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF Object Hash associated with a fake invoice and a W-9
#Matching PDF Object Hash associated with a fake invoice followed by a W-9.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.scan.pdf_obj_hash.object_hash == "cc08b7eae4b6f5f4e897dd0998b90e21"
)
)
Detection logic
Scope: inbound message.
Matching PDF Object Hash associated with a fake invoice followed by a W-9.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:- .scan.pdf_obj_hash.object_hash is 'cc08b7eae4b6f5f4e897dd0998b90e21'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.pdf_obj_hash.object_hash | equals | cc08b7eae4b6f5f4e897dd0998b90e21 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.pdf_obj_hash.object_hash eq "cc08b7eae4b6f5f4e897dd0998b90e21"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF Object Hash associated with fake Canada Revenue Agency documents
#Matching PDF Object Hash associated with chrome -> export to pdf of a shared document related to Canada's Revenue Agency.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.scan.pdf_obj_hash.object_hash == "cf509abbdc5aa6b1b759a216e3e570cf"
)
)
Detection logic
Scope: inbound message.
Matching PDF Object Hash associated with chrome -> export to pdf of a shared document related to Canada's Revenue Agency.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:- .scan.pdf_obj_hash.object_hash is 'cf509abbdc5aa6b1b759a216e3e570cf'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.pdf_obj_hash.object_hash | equals | cf509abbdc5aa6b1b759a216e3e570cf |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.pdf_obj_hash.object_hash eq "cf509abbdc5aa6b1b759a216e3e570cf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF Object Hash with Blue File Icon
#Detects PDF attachments containing a specific object hash (8638ef6bfe382a927aa12a18f2150757) associated with encrypted PDFs leading to cred phishing.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.scan.pdf_obj_hash.object_hash == "8638ef6bfe382a927aa12a18f2150757"
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a specific object hash (8638ef6bfe382a927aa12a18f2150757) associated with encrypted PDFs leading to cred phishing.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:- .scan.pdf_obj_hash.object_hash is '8638ef6bfe382a927aa12a18f2150757'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.pdf_obj_hash.object_hash | equals | 8638ef6bfe382a927aa12a18f2150757 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.pdf_obj_hash.object_hash eq "8638ef6bfe382a927aa12a18f2150757"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF proposal with credential theft indicators
#PDF attachment with 'proposal' in filename contains sender or recipient domain, credential theft language detected via OCR, and includes a single URL link.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and not (
(subject.is_reply or subject.is_forward)
and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
// a single PDFs
and length(filter(attachments, .file_type == "pdf")) == 1
and any(attachments,
.file_type == "pdf"
and regex.icontains(.file_name, '(?:proposal|bid|document|rf[pq])\b')
and beta.parse_exif(.).page_count == 1
// OCR is cred_theft
and any(ml.nlu_classifier(beta.ocr(.).text).intents,
.name == "cred_theft"
)
and length(beta.ocr(.).text) < 2000
and beta.ocr(.).success
// contains exactly one link on the root pdf
and any(file.explode(.),
.depth == 0
and length(.scan.url.urls) == 1
and all(.scan.url.urls,
.domain.root_domain not in (
'iso.org',
'w3.org',
'bfo.com', // pdf producer
'camscanner.com', // pdf producer
)
and not strings.istarts_with(.url, 'mailto')
)
)
)
// 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.
PDF attachment with 'proposal' in filename contains sender or recipient domain, credential theft language detected via OCR, and includes a single URL link.
- inbound message
not:
all of:
any of:
- subject.is_reply
- subject.is_forward
any of:
- length(headers.references) > 0
- headers.in_reply_to is set
- length(filter(attachments, .file_type == 'pdf')) is 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
- .file_name matches '(?:proposal|bid|document|rf[pq])\\b'
- beta.parse_exif(.).page_count is 1
any of
ml.nlu_classifier(beta.ocr(.).text).intentswhere:- .name is 'cred_theft'
- length(beta.ocr(.).text) < 2000
- beta.ocr(.).success
any of
file.explode(.)where all hold:- .depth is 0
- length(.scan.url.urls) is 1
all of
.scan.url.urlswhere all hold:- .domain.root_domain not in ('iso.org', 'w3.org', 'bfo.com', 'camscanner.com')
not:
- .url starts with 'mailto'
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, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: beta.ocr, beta.parse_exif, file.explode, ml.nlu_classifier, regex.icontains, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | (?:proposal|bid|document|rf[pq])\b |
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.url.urls length_compare "1"
macro "all(file.explode(attachments[])[].scan.url.urls)"
any(ml.nlu_classifier(beta.ocr(attachments).text).intents)
ml.nlu_classifier(beta.ocr(attachments).text).intents.name eq "cred_theft"
attachments.file_name regex_match "(?:proposal|bid|document|rf[pq])\\b"
attachments.file_type eq "pdf"
beta.ocr func_call "beta.ocr(attachments[]).success"
beta.ocr(attachments[]).text length_compare "2000"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
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
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
filter(attachments, .file_type == 'pdf') length_compare "1"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.in_reply_to | is_not_null | excludes:headers.in_reply_to | |
headers.references | length_compare | 0 | excludes:headers.references field:"headers.references" value:"0" |
subject.is_forward | eq | true | excludes:subject.is_forward field:"subject.is_forward" value:"true" |
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with a suspicious string and single URL
#Detects single-page PDF attachments containing suspicious language such as 'View Document' or 'View PDF' along with exactly one URL, commonly used in credential theft attacks.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
// a single page pdf
and beta.parse_exif(.).page_count == 1
and any(file.explode(.),
// the pdf contains specific suspicious wording
// these are exact matches when split on new lines extracted from the text of the PDF from the scanPDF scanner
any(.scan.strings.strings,
regex.icontains(.,
// action!
'^\s*(?:view documents?|view pdf|view presentation|preview new docusign|Download Secure PDF|VIEW DOCUMENT HERE|ACCESS DOCUMENT|REVIEW NEW SECURE DOCUMENT|OPEN SECURE VIEWER|DOWNLOAD RFP DOCUMENT|View Dashboard here|ACCESS SECURE DOCUMENTS|VIEW PROPOSAL DOCUMENTS|ACCESS / VIEW PROPOSAL DOCUMENT|Review & Sign Document|Open PDF|Access Document\(s\)|(?:P?RE)?VIEW SHARED DOCUMENT|New Secured Document|ACCESS SECURE RFP PORTAL|Please Review and Sign|Review and Validate|SECURE DOCUMENT|Open Document|View Details|Q!_Compensation/Salary Amendments\.pptx|PREVIEW DOCUMENT HERE|Download Tax Details Below:|Review and Sign Document|Review Document|Open Encrypted|OPEN DOCUMENT HERE|Click to read message|CLICK HERE TO VIEW DOCUMENTS|VIEW FULL DOCUMENT HERE)\s*$',
// "secure fax"
'View Secure Fax',
// more fake errors
'It seems there was an issue opening the document. Please view it online.',
// fake adobe update
'Update Adobe Viewer',
// fake sharepoint wording
'Learn more about messages protected by Microsoft',
// fake encryption crap
'This document is protected by 256-bit encryption.',
// sent you a document
'.*sent you a \S+ to review(?:\s*(?:and|&)\s*sign)$',
'^You received a \S+ to review and sign$',
// docusign
'\s*DocuSign Contract Under Review\s*',
'DOCUMENT PREVIEW',
'PREVIEW DOCUMENT',
'VIEW REMITTANCE COPY HERE',
'shared a file with you',
'(?:check your personal|view your) forecast',
'full new state pension',
'UN1TED STATES',
'view secure documents'
)
)
// fake error messages
or (
'Error' in~ .scan.strings.strings
and any(.scan.strings.strings,
regex.icontains(., '^\s*(?:View Video)\s*$')
)
)
// really terse PDF with link
or (
length(.scan.strings.strings) == 1
and 'Some additional information here' in~ .scan.strings.strings
)
)
and any(file.explode(.),
.depth == 0
and (
length(filter(.scan.url.urls,
// remove mailto: links
not strings.istarts_with(.url, 'mailto:')
and not strings.istarts_with(.url, 'email:')
// remove links found in exiftool output producer/creator
and not any([
..scan.exiftool.producer,
..scan.exiftool.creator
],
. is not null
and strings.icontains(.,
..domain.domain
)
)
and not .domain.root_domain in ('pdf-tools.com')
and not .url in (
'https://gamma.app/?utm_source=made-with-gamma'
)
)
) == 1
or
// there is only one unique domain
(
length(distinct(filter(.scan.url.urls,
// remove mailto: links
not strings.istarts_with(.url,
'mailto:'
)
and not strings.istarts_with(.url,
'email:'
)
// remove links found in exiftool output producer/creator
and not any([
..scan.exiftool.producer,
..scan.exiftool.creator
],
. is not null
and strings.icontains(.,
..domain.domain
)
)
and not .domain.root_domain in (
'pdf-tools.com'
)
and not .url in (
'https://gamma.app/?utm_source=made-with-gamma'
)
),
.domain.domain
)
) == 1
// all of them are in self_service
and all(distinct(filter(.scan.url.urls,
// remove mailto: links
not strings.istarts_with(.url,
'mailto:'
)
and not strings.istarts_with(.url,
'email:'
)
// remove links found in exiftool output producer/creator
and not any([
..scan.exiftool.producer,
..scan.exiftool.creator
],
. is not null
and strings.icontains(.,
..domain.domain
)
)
and not .domain.root_domain in (
'pdf-tools.com'
)
and not .url in (
'https://gamma.app/?utm_source=made-with-gamma'
)
),
.domain.domain
),
.domain.domain in $self_service_creation_platform_domains
or .domain.root_domain in $self_service_creation_platform_domains
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects single-page PDF attachments containing suspicious language such as 'View Document' or 'View PDF' along with exactly one URL, commonly used in credential theft attacks.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
- beta.parse_exif(.).page_count is 1
any of
file.explode(.)where any holds:any of
.scan.strings.stringswhere:. matches any of 17 patterns
^\s*(?:view documents?|view pdf|view presentation|preview new docusign|Download Secure PDF|VIEW DOCUMENT HERE|ACCESS DOCUMENT|REVIEW NEW SECURE DOCUMENT|OPEN SECURE VIEWER|DOWNLOAD RFP DOCUMENT|View Dashboard here|ACCESS SECURE DOCUMENTS|VIEW PROPOSAL DOCUMENTS|ACCESS / VIEW PROPOSAL DOCUMENT|Review & Sign Document|Open PDF|Access Document\(s\)|(?:P?RE)?VIEW SHARED DOCUMENT|New Secured Document|ACCESS SECURE RFP PORTAL|Please Review and Sign|Review and Validate|SECURE DOCUMENT|Open Document|View Details|Q!_Compensation/Salary Amendments\.pptx|PREVIEW DOCUMENT HERE|Download Tax Details Below:|Review and Sign Document|Review Document|Open Encrypted|OPEN DOCUMENT HERE|Click to read message|CLICK HERE TO VIEW DOCUMENTS|VIEW FULL DOCUMENT HERE)\s*$View Secure FaxIt seems there was an issue opening the document. Please view it online.Update Adobe ViewerLearn more about messages protected by MicrosoftThis document is protected by 256-bit encryption..*sent you a \S+ to review(?:\s*(?:and|&)\s*sign)$^You received a \S+ to review and sign$\s*DocuSign Contract Under Review\s*DOCUMENT PREVIEWPREVIEW DOCUMENTVIEW REMITTANCE COPY HEREshared a file with you(?:check your personal|view your) forecastfull new state pensionUN1TED STATESview secure documents
all of:
- .scan.strings.strings contains 'Error'
any of
.scan.strings.stringswhere:- . matches '^\\s*(?:View Video)\\s*$'
all of:
- length(.scan.strings.strings) is 1
- .scan.strings.strings contains 'Some additional information here'
any of
file.explode(.)where all hold:- .depth is 0
any of:
- length(filter(.scan.url.urls, not strings.istarts_with(.url, 'mailto:') and not strings.istarts_with(.url, 'email:') and not any([.scan.exiftool.producer, .scan.exiftool.creator], . is not null and strings.icontains(., .domain.domain)) and not .domain.root_domain in ('pdf-tools.com') and not .url in ('https://gamma.app/?utm_source=made-with-gamma'))) is 1
all of:
- length(distinct(filter(.scan.url.urls, not strings.istarts_with(.url, 'mailto:') and not strings.istarts_with(.url, 'email:') and not any([.scan.exiftool.producer, .scan.exiftool.creator], . is not null and strings.icontains(., .domain.domain)) and not .domain.root_domain in ('pdf-tools.com') and not .url in ('https://gamma.app/?utm_source=made-with-gamma')), .domain.domain)) is 1
all of
distinct(...)where any holds:- .domain.domain in $self_service_creation_platform_domains
- .domain.root_domain in $self_service_creation_platform_domains
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode, regex.icontains, strings.icontains, strings.istarts_with. Reference lists: $self_service_creation_platform_domains.
Indicators matched (21)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | ^\s*(?:view documents?|view pdf|view presentation|preview new docusign|Download Secure PDF|VIEW DOCUMENT HERE|ACCESS DOCUMENT|REVIEW NEW SECURE DOCUMENT|OPEN SECURE VIEWER|DOWNLOAD RFP DOCUMENT|View Dashboard here|ACCESS SECURE DOCUMENTS|VIEW PROPOSAL DOCUMENTS|ACCESS / VIEW PROPOSAL DOCUMENT|Review & Sign Document|Open PDF|Access Document\(s\)|(?:P?RE)?VIEW SHARED DOCUMENT|New Secured Document|ACCESS SECURE RFP PORTAL|Please Review and Sign|Review and Validate|SECURE DOCUMENT|Open Document|View Details|Q!_Compensation/Salary Amendments\.pptx|PREVIEW DOCUMENT HERE|Download Tax Details Below:|Review and Sign Document|Review Document|Open Encrypted|OPEN DOCUMENT HERE|Click to read message|CLICK HERE TO VIEW DOCUMENTS|VIEW FULL DOCUMENT HERE)\s*$ |
regex.icontains | regex | View Secure Fax |
regex.icontains | regex | It seems there was an issue opening the document. Please view it online. |
regex.icontains | regex | Update Adobe Viewer |
regex.icontains | regex | Learn more about messages protected by Microsoft |
regex.icontains | regex | This document is protected by 256-bit encryption. |
regex.icontains | regex | .*sent you a \S+ to review(?:\s*(?:and|&)\s*sign)$ |
regex.icontains | regex | ^You received a \S+ to review and sign$ |
regex.icontains | regex | \s*DocuSign Contract Under Review\s* |
regex.icontains | regex | DOCUMENT PREVIEW |
regex.icontains | regex | PREVIEW DOCUMENT |
9 more
regex.icontains | regex | VIEW REMITTANCE COPY HERE |
regex.icontains | regex | shared a file with you |
regex.icontains | regex | (?:check your personal|view your) forecast |
regex.icontains | regex | full new state pension |
regex.icontains | regex | UN1TED STATES |
regex.icontains | regex | view secure documents |
file.explode(attachments[])[].scan.strings.strings | contains | Error |
regex.icontains | regex | ^\s*(?:View Video)\s*$ |
file.explode(attachments[])[].scan.strings.strings | contains | Some additional information here |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
and
distinct(filter(file.explode(attachments[])[].scan.url.urls, not strings.istarts_with(file.explode(attachments[])[].url, 'mailto:') and not strings.istarts_with(file.explode(attachments[])[].url, 'email:') and not any([attachments[].scan.exiftool.producer, attachments[].scan.exiftool.creator], file.explode(attachments[])[] is not null and strings.icontains(file.explode(attachments[])[], attachments[].domain.domain)) and not file.explode(attachments[])[].domain.root_domain in ('pdf-tools.com') and not file.explode(attachments[])[].url in ('https://gamma.app/?utm_source=made-with-gamma')), file.explode(attachments[])[].domain.domain) length_compare "1"
macro "all(distinct(...))"
filter(file.explode(attachments[])[].scan.url.urls, not strings.istarts_with(file.explode(attachments[])[].url, 'mailto:') and not strings.istarts_with(file.explode(attachments[])[].url, 'email:') and not any([attachments[].scan.exiftool.producer, attachments[].scan.exiftool.creator], file.explode(attachments[])[] is not null and strings.icontains(file.explode(attachments[])[], attachments[].domain.domain)) and not file.explode(attachments[])[].domain.root_domain in ('pdf-tools.com') and not file.explode(attachments[])[].url in ('https://gamma.app/?utm_source=made-with-gamma')) length_compare "1"
file.explode(attachments[])[].depth eq "0"
any(file.explode(attachments))
or
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "^\\s*(?:View Video)\\s*$"
file.explode(attachments[])[].scan.strings.strings contains "Error"
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] regex_match "(?:check your personal|view your) forecast"
file.explode(attachments[])[].scan.strings.strings[] regex_match ".*sent you a \\S+ to review(?:\\s*(?:and|&)\\s*sign)$"
file.explode(attachments[])[].scan.strings.strings[] regex_match "DOCUMENT PREVIEW"
file.explode(attachments[])[].scan.strings.strings[] regex_match "It seems there was an issue opening the document. Please view it online."
file.explode(attachments[])[].scan.strings.strings[] regex_match "Learn more about messages protected by Microsoft"
file.explode(attachments[])[].scan.strings.strings[] regex_match "PREVIEW DOCUMENT"
file.explode(attachments[])[].scan.strings.strings[] regex_match "This document is protected by 256-bit encryption."
file.explode(attachments[])[].scan.strings.strings[] regex_match "UN1TED STATES"
file.explode(attachments[])[].scan.strings.strings[] regex_match "Update Adobe Viewer"
file.explode(attachments[])[].scan.strings.strings[] regex_match "VIEW REMITTANCE COPY HERE"
file.explode(attachments[])[].scan.strings.strings[] regex_match "View Secure Fax"
file.explode(attachments[])[].scan.strings.strings[] regex_match "\\s*DocuSign Contract Under Review\\s*"
file.explode(attachments[])[].scan.strings.strings[] regex_match "^You received a \\S+ to review and sign$"
file.explode(attachments[])[].scan.strings.strings[] regex_match "^\\s*(?:view documents?|view pdf|view presentation|preview new docusign|Download Secure PDF|VIEW DOCUMENT HERE|ACCESS DOCUMENT|REVIEW NEW SECURE DOCUMENT|OPEN SECURE VIEWER|DOWNLOAD RFP DOCUMENT|View Dashboard here|ACCESS SECURE DOCUMENTS|VIEW PROPOSAL DOCUMENTS|ACCESS / VIEW PROPOSAL DOCUMENT|Review & Sign Document|Open PDF|Access Document\\(s\\)|(?:P?RE)?VIEW SHARED DOCUMENT|New Secured Document|ACCESS SECURE RFP PORTAL|Please Review and Sign|Review and Validate|SECURE DOCUMENT|Open Document|View Details|Q!_Compensation/Salary Amendments\\.pptx|PREVIEW DOCUMENT HERE|Download Tax Details Below:|Review and Sign Document|Review Document|Open Encrypted|OPEN DOCUMENT HERE|Click to read message|CLICK HERE TO VIEW DOCUMENTS|VIEW FULL DOCUMENT HERE)\\s*$"
file.explode(attachments[])[].scan.strings.strings[] regex_match "full new state pension"
file.explode(attachments[])[].scan.strings.strings[] regex_match "shared a file with you"
file.explode(attachments[])[].scan.strings.strings[] regex_match "view secure documents"
and
file.explode(attachments[])[].scan.strings.strings contains "Some additional information here"
file.explode(attachments[])[].scan.strings.strings length_compare "1"
attachments.file_type eq "pdf"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with base64 JavaScript and eval functions
#PDF attachment contains base64-encoded JavaScript variables with eval functions, indicating potential code obfuscation and execution techniques commonly used in malicious documents.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.depth == 0
and any(.scan.yara.matches, .name in ("pdf_b64_js_var_eval", ))
)
)
Detection logic
Scope: inbound message.
PDF attachment contains base64-encoded JavaScript variables with eval functions, indicating potential code obfuscation and execution techniques commonly used in malicious documents.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .depth is 0
any of
.scan.yara.matcheswhere:- .name in ('pdf_b64_js_var_eval')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_b64_js_var_eval |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_b64_js_var_eval"
file.explode(filter(attachments)[])[].depth eq "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with blurry lure image
#Detects PDF attachments containing a blurry image used in credential phishing lures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("pdf_lure_image_blurry", ))
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a blurry image used in credential phishing lures.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_lure_image_blurry')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_lure_image_blurry |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_lure_image_blurry"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with credential theft language and invalid reply-to domain
#Detects PDF attachments containing high-confidence credential theft language that references the recipient's email address, combined with an invalid reply-to domain header.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Spoofing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(headers.reply_to, .email.email == "")
and any(attachments,
.file_type == 'pdf'
and any(file.explode(.),
any(ml.nlu_classifier(.scan.strings.raw).intents,
.name == 'cred_theft' and .confidence == 'high'
)
and strings.icontains(.scan.strings.raw,
recipients.to[0].email.email
)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication or DMARC is missing
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 PDF attachments containing high-confidence credential theft language that references the recipient's email address, combined with an invalid reply-to domain header.
- inbound message
- length(recipients.to) is 1
- recipients.to[0].email.domain.valid
any of
headers.reply_towhere:- .email.email is ''
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where all hold:any of
ml.nlu_classifier(.scan.strings.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
- strings.icontains(.scan.strings.raw)
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.email, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.nlu_classifier, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
headers.reply_to[].email.email | equals | |
attachments[].file_type | equals | pdf |
ml.nlu_classifier(file.explode(attachments[])[].scan.strings.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.strings.raw).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(ml.nlu_classifier(file.explode(attachments).scan.strings.raw).intents)
and
ml.nlu_classifier(file.explode(attachments[])[].scan.strings.raw).intents[].confidence eq "high"
ml.nlu_classifier(file.explode(attachments[])[].scan.strings.raw).intents[].name eq "cred_theft"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.strings.raw)"
attachments.file_type eq "pdf"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
any(headers.reply_to)
headers.reply_to.email.email eq ""
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.
Attachment: PDF with credential theft language and link to a free subdomain (unsolicited)
#Detects messages with credential theft PDFs linking to free subdomains.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free subdomain host, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence in ("medium", "high")
)
and any(attachments,
.file_extension == "pdf"
and any(file.explode(.),
any(.scan.pdf.urls,
.domain.root_domain in $free_subdomain_hosts
and .domain.subdomain is not null
and .domain.subdomain != "www"
)
and any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft"
and .confidence in ("medium", "high")
)
)
)
// unsolicited
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.
Detects messages with credential theft PDFs linking to free subdomains.
- inbound message
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where all hold:any of
.scan.pdf.urlswhere all hold:- .domain.root_domain in $free_subdomain_hosts
- .domain.subdomain is set
- .domain.subdomain is not 'www'
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
any of:
not:
- profile.by_sender().solicited
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_extension, body.current_thread.text, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender. Reference lists: $free_subdomain_hosts.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | member | medium |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | member | high |
attachments[].file_extension | equals | pdf |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | member | medium |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | member | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.pdf.urls)
and
file.explode(attachments[])[].scan.pdf.urls[].domain.subdomain is_not_null
file.explode(attachments[])[].scan.pdf.urls[].domain.subdomain ne "www"
macro "file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain in free_subdomain_hosts"
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"
attachments.file_extension eq "pdf"
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"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with CVE-2026-34621 lures
#Detects PDF attachments containing YARA signatures associated with CVE-2026-34621's observed lures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.depth == 0
and any(.scan.yara.matches,
.name == "pdf_cve_2026_34621_observed_lures"
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing YARA signatures associated with CVE-2026-34621's observed lures.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .depth is 0
any of
.scan.yara.matcheswhere:- .name is 'pdf_cve_2026_34621_observed_lures'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | equals | pdf_cve_2026_34621_observed_lures |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_cve_2026_34621_observed_lures"
file.explode(filter(attachments)[])[].depth eq "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with eCheckRun lures
#Detects PDF attachments matching yara rules looking for attachments containing artifacts from related to fake financial/invoice themes, including eCheckRun lures. These are commonly used to trick users into believe they have received legitmate electronic payment messages.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("pdf_eCheckLure_format", ))
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments matching yara rules looking for attachments containing artifacts from related to fake financial/invoice themes, including eCheckRun lures. These are commonly used to trick users into believe they have received legitmate electronic payment messages.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_eCheckLure_format')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_eCheckLure_format |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_eCheckLure_format"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with fake invoice using suspicious font sizing
#PDF attachment contains a fake invoice with suspicious font size patterns and unique image sizes, typically used in fraudulent billing schemes.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Callback Phishing |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name == "pdf_fake_invoice_image_font_sizes"
)
)
)
Detection logic
Scope: inbound message.
PDF attachment contains a fake invoice with suspicious font size patterns and unique image sizes, typically used in fraudulent billing schemes.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'pdf_fake_invoice_image_font_sizes'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | equals | pdf_fake_invoice_image_font_sizes |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_fake_invoice_image_font_sizes"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with JSFck obfuscation
#PDF attachment contains JavaScript obfuscated using JSFck encoding techniques. JSFck is a method of writing JavaScript code using only six characters: !+ which is often used to evade detection by security tools.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.depth == 0
and any(.scan.yara.matches,
.name in ("pdf_jsfck_strings", "pdf_jsfck_ratio")
)
)
)
Detection logic
Scope: inbound message.
PDF attachment contains JavaScript obfuscated using JSFck encoding techniques. JSFck is a method of writing JavaScript code using only six characters: !+ which is often used to evade detection by security tools.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .depth is 0
any of
.scan.yara.matcheswhere:- .name in ('pdf_jsfck_strings', 'pdf_jsfck_ratio')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_jsfck_strings |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_jsfck_ratio |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name in ["pdf_jsfck_ratio", "pdf_jsfck_strings"]
file.explode(filter(attachments)[])[].depth eq "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with link to DMG file download
#This rule identifies PDF attachments that either link directly to a DMG file, link to a ZIP archive containing a DMG file, or link to an encrypted ZIP containing a DMG file. This technique has been observed delivering MetaStealer Malware.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
any(.scan.url.urls,
// url links to dmg or zip
(
strings.iends_with(.url, ".dmg")
or strings.iends_with(.url, "zip")
)
// and downloads a dmg or a zip
and any(ml.link_analysis(.).files_downloaded,
(
.file_extension == "dmg"
or (
.file_extension in~ $file_extensions_common_archives
// and the zip contains a dmg file
and any(file.explode(.),
(.file_extension =~ "dmg")
// exif inspection if encrypted
or strings.ends_with(.scan.exiftool.zip_file_name,
".dmg"
)
)
)
)
)
)
)
)
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.
This rule identifies PDF attachments that either link directly to a DMG file, link to a ZIP archive containing a DMG file, or link to an encrypted ZIP containing a DMG file. This technique has been observed delivering MetaStealer Malware.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where:any of
.scan.url.urlswhere all hold:any of:
- .url ends with '.dmg'
- .url ends with 'zip'
any of
ml.link_analysis(.).files_downloadedwhere any holds:- .file_extension is 'dmg'
all of:
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where any holds:- .file_extension is 'dmg'
- .scan.exiftool.zip_file_name ends with '.dmg'
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: attachments[].file_type, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.ends_with, strings.iends_with. Reference lists: $file_extensions_common_archives.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.iends_with | suffix | .dmg |
strings.iends_with | suffix | zip |
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[].file_extension | equals | dmg |
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].file_extension | equals | dmg |
strings.ends_with | suffix | .dmg |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
any(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded)
or
and
any(file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded))
or
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].file_extension eq "dmg"
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].scan.exiftool.zip_file_name ends_with ".dmg"
macro "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[].file_extension in file_extensions_common_archives"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[].file_extension eq "dmg"
or
file.explode(attachments[])[].scan.url.urls[].url ends_with ".dmg"
file.explode(attachments[])[].scan.url.urls[].url ends_with "zip"
attachments.file_type eq "pdf"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with link to zip containing a wsf file
#Detects a PDF attachment with a link to a ZIP file that contains a WSF file
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
any(.scan.url.urls,
strings.icontains(.url, "zip")
and any(ml.link_analysis(.).files_downloaded,
any(file.explode(.), .file_extension == "wsf")
)
)
or any(.scan.url.urls,
strings.icontains(.url, "php")
and any(ml.link_analysis(.).files_downloaded,
any(file.explode(.),
.file_extension == "zip"
and any(.scan.zip.attempted_files,
strings.icontains(., "wsf")
)
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects a PDF attachment with a link to a ZIP file that contains a WSF file
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where any holds:any of
.scan.url.urlswhere all hold:- .url contains 'zip'
any of
ml.link_analysis(.).files_downloadedwhere:any of
file.explode(.)where:- .file_extension is 'wsf'
any of
.scan.url.urlswhere all hold:- .url contains 'php'
any of
ml.link_analysis(.).files_downloadedwhere:any of
file.explode(.)where all hold:- .file_extension is 'zip'
any of
.scan.zip.attempted_fileswhere:- . contains 'wsf'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, ml.link_analysis, strings.icontains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | zip |
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].file_extension | equals | wsf |
strings.icontains | substring | php |
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].file_extension | equals | zip |
strings.icontains | substring | wsf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.url.urls)
and
any(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded)
any(file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded))
and
any(file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded).scan.zip.attempted_files)
file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded).scan.zip.attempted_files contains "wsf"
file.explode(ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).files_downloaded[])[].file_extension eq "zip"
file.explode(attachments[])[].scan.url.urls[].url contains "php"
any(file.explode(attachments).scan.url.urls)
and
any(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded)
any(file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded))
file.explode(ml.link_analysis(file.explode(attachments).scan.url.urls).files_downloaded).file_extension eq "wsf"
file.explode(attachments[])[].scan.url.urls[].url contains "zip"
attachments.file_type eq "pdf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with localhost IP in EXIF title metadata
#Detects inbound PDF attachments where the EXIF title metadata starts with '127.0.0.1', sent either to a self-addressed recipient or an invalid recipient domain. This technique may indicate automated or malicious document generation tools embedding localhost references in file metadata.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// self sender or invaild recipent domain
and length(recipients.to) == 1
and (
sender.email.email == recipients.to[0].email.email
or recipients.to[0].email.domain.valid == false
)
and any(filter(attachments, .file_type == "pdf"),
strings.starts_with(beta.parse_exif(.).title, "127.0.0.1")
)
Detection logic
Scope: inbound message.
Detects inbound PDF attachments where the EXIF title metadata starts with '127.0.0.1', sent either to a self-addressed recipient or an invalid recipient domain. This technique may indicate automated or malicious document generation tools embedding localhost references in file metadata.
- inbound message
- length(recipients.to) is 1
any of:
- sender.email.email is recipients.to[0].email.email
- recipients.to[0].email.domain.valid is False
any of
filter(attachments)where:- beta.parse_exif(.).title starts with '127.0.0.1'
Inspects: attachments[].file_type, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: beta.parse_exif, strings.starts_with.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | 127.0.0.1 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
beta.parse_exif(filter(attachments)[]).title starts_with "127.0.0.1"
or
recipients.to[0].email.domain.valid eq "false"
sender.email.email cross_field_compare "recipients.to[0].email.email"
recipients.to length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
recipients.to[0].email.domain.valid | eq |
| field:"recipients.to[0].email.domain.valid" kind:eq value:"false" |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with Microsoft Purview message impersonation
#Detects PDF attachments containing text that impersonates Microsoft Purview secure message notifications, potentially used to trick users into believing they have received legitimate secure communications from Microsoft services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_extension == 'pdf'),
any(ml.nlu_classifier(beta.ocr(.).text).topics,
.name == 'Secure Message' and .confidence == 'high'
)
and strings.icontains(beta.ocr(.).text, "Microsoft Purview Message")
)
// 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 PDF attachments containing text that impersonates Microsoft Purview secure message notifications, potentially used to trick users into believing they have received legitimate secure communications from Microsoft services.
- inbound message
any of
filter(attachments)where all hold:any of
ml.nlu_classifier(beta.ocr(.).text).topicswhere all hold:- .name is 'Secure Message'
- .confidence is 'high'
- beta.ocr(.).text contains 'Microsoft Purview Message'
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_extension, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.ocr, ml.nlu_classifier, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
ml.nlu_classifier(beta.ocr(filter(attachments)[]).text).topics[].name | equals | Secure Message |
ml.nlu_classifier(beta.ocr(filter(attachments)[]).text).topics[].confidence | equals | high |
strings.icontains | substring | Microsoft Purview Message |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(ml.nlu_classifier(beta.ocr(filter(attachments)).text).topics)
and
ml.nlu_classifier(beta.ocr(filter(attachments)[]).text).topics[].confidence eq "high"
ml.nlu_classifier(beta.ocr(filter(attachments)[]).text).topics[].name eq "Secure Message"
beta.ocr(filter(attachments)[]).text contains "Microsoft Purview Message"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with multistage landing - ClickUp abuse
#Detects PDF attachments containing ClickUp document links that either redirect to unavailable pages or contain embedded links leading to newly registered domains, free file hosts, URL shorteners, or verified credential theft pages.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Free file host, Free subdomain host, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
.depth == 0
and length(.scan.url.urls) == 1
and any(.scan.url.urls,
.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 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 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 PDF attachments containing ClickUp document links that either redirect to unavailable pages or contain embedded links leading to newly registered domains, free file hosts, URL shorteners, or verified credential theft pages.
- inbound message
- length(attachments) is 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where all hold:- .depth is 0
- length(.scan.url.urls) is 1
any of
.scan.url.urlswhere all hold:- .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: attachments[].file_type, type.inbound. Sensors: file.explode, 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 (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(attachments[])[].scan.url.urls[].domain.domain | equals | doc.clickup.com |
strings.istarts_with | prefix | This page is currently unavailable |
regex.icontains | regex | (?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
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(file.explode(attachments[])[].scan.url.urls[]).final_dom.display_text starts_with "This page is currently unavailable"
file.explode(attachments[])[].scan.url.urls[].domain.domain eq "doc.clickup.com"
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.url.urls length_compare "1"
attachments.file_type eq "pdf"
attachments length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with password in filename matching body text
#Detects messages containing a single PDF attachment where the filename includes a numeric password that is explicitly referenced in the message body text.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Encryption, Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type == "pdf")) == 1
and any(regex.extract(body.current_thread.text, 'password is (?P<pw>[0-9]{1,})'),
any(filter(attachments, .file_type == "pdf"),
strings.contains(.file_name, ..named_groups["pw"])
)
)
Detection logic
Scope: inbound message.
Detects messages containing a single PDF attachment where the filename includes a numeric password that is explicitly referenced in the message body text.
- inbound message
- length(filter(attachments, .file_type == 'pdf')) is 1
any of
regex.extract(body.current_thread.text)where:any of
filter(attachments)where:- strings.contains(.file_name)
Inspects: attachments[].file_type, body.current_thread.text, type.inbound. Sensors: regex.extract, strings.contains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.extract | regex | password is (?P<pw>[0-9]{1,}) |
Stages and Predicates
Stage 1: mql_rule
and
any(regex.extract(body.current_thread.text))
any(filter(attachments))
strings.contains func_call "strings.contains(filter(attachments)[].file_name)"
filter(attachments, .file_type == 'pdf') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with personal Microsoft OneNote URL
#Detects PDF attachments containing a sharepoint URL referencing the senders personal OneNote.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type == "pdf")) >= 1
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
any(.scan.url.urls,
strings.icontains(.path,
strings.concat("/:o:/p/",
sender.email.local_part
)
)
or strings.icontains(.path, "/:o:/g/personal/")
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a sharepoint URL referencing the senders personal OneNote.
- inbound message
- length(filter(attachments, .file_type == 'pdf')) ≥ 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where:any of
.scan.url.urlswhere any holds:- strings.icontains(.path)
- .path contains '/:o:/g/personal/'
Inspects: attachments[].file_type, sender.email.local_part, type.inbound. Sensors: file.explode, strings.concat, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | /:o:/g/personal/ |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
or
file.explode(attachments[])[].scan.url.urls[].path contains "/:o:/g/personal/"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.url.urls[].path)"
attachments.file_type eq "pdf"
filter(attachments, .file_type == 'pdf') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with QR code containing recipient-specific credential theft content
#Detects PDF attachments containing QR codes that include the recipient's email address (either plaintext or base64 encoded) combined with credential theft language detected through natural language processing. This technique personalizes the attack by incorporating the target's email into the QR code URL while using PDF content to establish credibility.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
( // the strings produced by the PDF scanner contains cred theft language
any(filter(file.explode(.), .depth == 1 and .file_name == "text"),
any(ml.nlu_classifier(.scan.strings.raw).intents,
.name == "cred_theft"
)
)
)
// there is a QR code
and length(beta.scan_qr(.).items) > 0
// QR code contians the recipient email
and any(beta.scan_qr(.).items,
.url.domain.valid
and any(recipients.to,
.email.domain.valid
// QR code contains the email
and (
strings.icontains(..url.url, .email.email)
// QR code contains the base64 endcoded email
or any(strings.scan_base64(..url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing QR codes that include the recipient's email address (either plaintext or base64 encoded) combined with credential theft language detected through natural language processing. This technique personalizes the attack by incorporating the target's email into the QR code URL while using PDF content to establish credibility.
- inbound message
any of
filter(attachments)where all hold:any of
filter(...)where:any of
ml.nlu_classifier(.scan.strings.raw).intentswhere:- .name is 'cred_theft'
- length(beta.scan_qr(.).items) > 0
any of
beta.scan_qr(.).itemswhere all hold:- .url.domain.valid
any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.url.url)
any of
strings.scan_base64(.url.url)where:- strings.icontains(.)
Inspects: attachments[].file_type, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: beta.scan_qr, file.explode, ml.nlu_classifier, strings.icontains, strings.scan_base64.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].file_name | equals | text |
ml.nlu_classifier(filter(...)[].scan.strings.raw).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
any(beta.scan_qr(filter(attachments)).items)
and
any(recipients.to)
and
or
any(strings.scan_base64(beta.scan_qr(filter(attachments)).items.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(beta.scan_qr(filter(attachments)[]).items[].url.url)[])"
strings.icontains func_call "strings.icontains(beta.scan_qr(filter(attachments)[]).items[].url.url)"
recipients.to.email.domain.valid eq "true"
beta.scan_qr(filter(attachments)[]).items[].url.domain.valid eq "true"
any(filter(...))
any(ml.nlu_classifier(filter(...).scan.strings.raw).intents)
ml.nlu_classifier(filter(...).scan.strings.raw).intents.name eq "cred_theft"
beta.scan_qr(filter(attachments)[]).items length_compare "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with quote lure
#Detects PDF attachments containing quote-themed lure content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("pdf_quote_lure_01"))
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing quote-themed lure content.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_quote_lure_01')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_quote_lure_01 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_quote_lure_01"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with recipient email in link
#Detects PDF attachments that contain the recipient's domain in the filename and include a link personalized with the recipient's email address, either in the URL directly, encoded in base64, or within a QR code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, QR code, Encryption, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// one or more PDF documents
and length(filter(attachments, .file_type == "pdf")) >= 1
and length(attachments) <= 4
// a single recipient (this is in the link so there can be only one)
and length(recipients.to) == 1
and all(recipients.to, .email.domain.valid)
and any(filter(attachments, .file_type == "pdf"),
(
// the urls in the PDF
any(filter(file.explode(.), .depth == 0),
// remove links we are not interested in
any(filter(.scan.pdf.urls,
// remove mailto: links
not strings.istarts_with(.url, 'mailto:')
and not strings.istarts_with(.url, 'email:')
// remove links found in exiftool output
and not (
..scan.exiftool.producer is not null
and strings.icontains(..scan.exiftool.producer,
.domain.domain
)
)
// remove links found in exiftool output
and not (
..scan.exiftool.creator is not null
and strings.icontains(..scan.exiftool.creator,
.domain.domain
)
)
// legitimate domains that exhibits this behavior
and .domain.root_domain not in (
"univarsolutions.com",
"westpac.com.au",
"safeshiphub.com",
"sharepoint.com"
)
),
// it contains the email address of the recipient
any(recipients.to,
.email.domain.valid
and (
strings.icontains(..url, .email.email)
// or the base64 encoded email
or any(beta.scan_base64(..url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
)
)
// or there is a QR code
or (
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
any(beta.scan_qr(.).items,
.url.domain.valid
and any(recipients.to,
// QR code contains the email
(
strings.icontains(..url.url, .email.email)
// QR code contains the base64 endcoded email
or any(strings.scan_base64(..url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments that contain the recipient's domain in the filename and include a link personalized with the recipient's email address, either in the URL directly, encoded in base64, or within a QR code.
- inbound message
- length(filter(attachments, .file_type == 'pdf')) ≥ 1
- length(attachments) ≤ 4
- length(recipients.to) is 1
all of
recipients.towhere:- .email.domain.valid
any of
filter(attachments)where any holds:any of
filter(...)where:any of
filter(.scan.pdf.urls)where:any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.url)
any of
beta.scan_base64(.url)where:- strings.icontains(.)
any of
beta.scan_qr(.).itemswhere all hold:- .url.domain.valid
any of
recipients.towhere any holds:- strings.icontains(.url.url)
any of
strings.scan_base64(.url.url)where:- strings.icontains(.)
Inspects: attachments[].file_type, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: beta.scan_base64, beta.scan_qr, file.explode, strings.icontains, strings.istarts_with, strings.scan_base64.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
or
any(filter(...))
any(filter(filter(...).scan.pdf.urls))
any(recipients.to)
and
or
any(beta.scan_base64(filter(filter(...).scan.pdf.urls).url))
strings.icontains func_call "strings.icontains(beta.scan_base64(filter(filter(...)[].scan.pdf.urls)[].url)[])"
strings.icontains func_call "strings.icontains(filter(filter(...)[].scan.pdf.urls)[].url)"
recipients.to.email.domain.valid eq "true"
any(beta.scan_qr(filter(attachments)).items)
and
any(recipients.to)
or
any(strings.scan_base64(beta.scan_qr(filter(attachments)).items.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(beta.scan_qr(filter(attachments)[]).items[].url.url)[])"
strings.icontains func_call "strings.icontains(beta.scan_qr(filter(attachments)[]).items[].url.url)"
beta.scan_qr(filter(attachments)[]).items[].url.domain.valid eq "true"
attachments length_compare "4"
filter(attachments, .file_type == 'pdf') length_compare "1"
recipients.to length_compare "1"
type.inbound eq "true"
macro "all(recipients.to)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with ReportLab library and default metadata
#Detects PDF attachments generated using the ReportLab PDF Library with default anonymous metadata values, including untitled document, anonymous creator/author, and unspecified subject. This combination of characteristics is commonly associated with automated PDF generation tools used in malicious activities.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
beta.parse_exif(.).producer == "ReportLab PDF Library - (opensource)"
and beta.parse_exif(.).title == "untitled"
and beta.parse_exif(.).creator == "anonymous"
and any(beta.parse_exif(.).fields,
.key == "Subject" and .value == "unspecified"
)
and beta.parse_exif(.).author == "anonymous"
)
Detection logic
Scope: inbound message.
Detects PDF attachments generated using the ReportLab PDF Library with default anonymous metadata values, including untitled document, anonymous creator/author, and unspecified subject. This combination of characteristics is commonly associated with automated PDF generation tools used in malicious activities.
- inbound message
any of
attachmentswhere all hold:- beta.parse_exif(.).producer is 'ReportLab PDF Library - (opensource)'
- beta.parse_exif(.).title is 'untitled'
- beta.parse_exif(.).creator is 'anonymous'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Subject'
- .value is 'unspecified'
- beta.parse_exif(.).author is 'anonymous'
Inspects: type.inbound. Sensors: beta.parse_exif.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
beta.parse_exif(attachments[]).fields[].key | equals | Subject |
beta.parse_exif(attachments[]).fields[].value | equals | unspecified |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(beta.parse_exif(attachments).fields)
and
beta.parse_exif(attachments[]).fields[].key eq "Subject"
beta.parse_exif(attachments[]).fields[].value eq "unspecified"
beta.parse_exif func_call "beta.parse_exif(attachments[]).author == anonymous"
beta.parse_exif func_call "beta.parse_exif(attachments[]).creator == anonymous"
beta.parse_exif func_call "beta.parse_exif(attachments[]).producer == ReportLab PDF Library - (opensource)"
beta.parse_exif func_call "beta.parse_exif(attachments[]).title == untitled"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF With SAI Global ISO9001 Logo
#Detects PDF attachments containing embedded SAI Global ISO9001 logos, which may indicate brand impersonation or fraudulent certification claims.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
// yara rule matches on an embedded SAI Global logo that allows for resized versions of the image
.name == "SAI_Global_ISO9001_Logo_PDF_Fuzzy"
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing embedded SAI Global ISO9001 logos, which may indicate brand impersonation or fraudulent certification claims.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'SAI_Global_ISO9001_Logo_PDF_Fuzzy'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | equals | SAI_Global_ISO9001_Logo_PDF_Fuzzy |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "SAI_Global_ISO9001_Logo_PDF_Fuzzy"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with secure document acknowledgment prompt
#Detects PDF attachments matching yara rules looking for fake secure document prompts, including acknowledgment-style lures and suspicious image sizing.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, PDF, Social engineering, Image as content, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name in (
"pdf_prompt_ack_secure_document_link",
"pdf_prompt_ack_secure_document_image_sizes"
)
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments matching yara rules looking for fake secure document prompts, including acknowledgment-style lures and suspicious image sizing.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_prompt_ack_secure_document_link', 'pdf_prompt_ack_secure_document_image_sizes')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_prompt_ack_secure_document_link |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_prompt_ack_secure_document_image_sizes |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name in ["pdf_prompt_ack_secure_document_image_sizes", "pdf_prompt_ack_secure_document_link"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with self-service platform links with self sender or blank recipients
#Detects single-page PDF attachments containing links to self-service content creation platforms, sent to either the sender's own email address or an invalid email domain. This pattern may indicate testing of malicious content or preparation for distribution.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | PDF, Evasion, Free file host |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and sum([length(recipients.to), length(recipients.cc)]) == 1
and (
sender.email.email == recipients.to[0].email.email
or recipients.to[0].email.domain.valid == false
)
and length(attachments) == 1
and beta.parse_exif(attachments[0]).page_count == 1
and any(filter(attachments, .file_type == "pdf"),
any(filter(file.explode(.), .depth == 0),
1 <= length(filter(.scan.url.urls,
// remove mailto: links
not strings.istarts_with(.url, 'mailto:')
and not strings.istarts_with(.url, 'email:')
// remove links found in exiftool output producer/creator
and not any([
..scan.exiftool.producer,
..scan.exiftool.creator
],
. is not null
and strings.icontains(.,
..domain.domain
)
)
and not .domain.root_domain in ('pdf-tools.com')
and not .url in (
'https://gamma.app/?utm_source=made-with-gamma'
)
)
) <= 3
and all(.scan.url.urls,
.domain.root_domain in $self_service_creation_platform_domains
or .domain.domain in $self_service_creation_platform_domains
)
)
)
Detection logic
Scope: inbound message.
Detects single-page PDF attachments containing links to self-service content creation platforms, sent to either the sender's own email address or an invalid email domain. This pattern may indicate testing of malicious content or preparation for distribution.
- inbound message
- sum([length(recipients.to), length(recipients.cc)]) is 1
any of:
- sender.email.email is recipients.to[0].email.email
- recipients.to[0].email.domain.valid is False
- length(attachments) is 1
- beta.parse_exif(attachments[0]).page_count is 1
any of
filter(attachments)where:any of
filter(...)where all hold:all of:
- length(filter(.scan.url.urls, not strings.istarts_with(.url, 'mailto:') and not strings.istarts_with(.url, 'email:') and not any([.scan.exiftool.producer, .scan.exiftool.creator], . is not null and strings.icontains(., .domain.domain)) and not .domain.root_domain in ('pdf-tools.com') and not .url in ('https://gamma.app/?utm_source=made-with-gamma'))) ≥ 1
- length(filter(.scan.url.urls, not strings.istarts_with(.url, 'mailto:') and not strings.istarts_with(.url, 'email:') and not any([.scan.exiftool.producer, .scan.exiftool.creator], . is not null and strings.icontains(., .domain.domain)) and not .domain.root_domain in ('pdf-tools.com') and not .url in ('https://gamma.app/?utm_source=made-with-gamma'))) ≤ 3
all of
.scan.url.urlswhere any holds:- .domain.root_domain in $self_service_creation_platform_domains
- .domain.domain in $self_service_creation_platform_domains
Inspects: attachments[0], attachments[].file_type, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: beta.parse_exif, file.explode, strings.icontains, strings.istarts_with. Reference lists: $self_service_creation_platform_domains.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(filter(...))
and
filter(filter(...)[].scan.url.urls, not strings.istarts_with(filter(...)[].url, 'mailto:') and not strings.istarts_with(filter(...)[].url, 'email:') and not any([filter(attachments)[].scan.exiftool.producer, filter(attachments)[].scan.exiftool.creator], filter(...)[] is not null and strings.icontains(filter(...)[], filter(attachments)[].domain.domain)) and not filter(...)[].domain.root_domain in ('pdf-tools.com') and not filter(...)[].url in ('https://gamma.app/?utm_source=made-with-gamma')) length_compare "1"
filter(filter(...)[].scan.url.urls, not strings.istarts_with(filter(...)[].url, 'mailto:') and not strings.istarts_with(filter(...)[].url, 'email:') and not any([filter(attachments)[].scan.exiftool.producer, filter(attachments)[].scan.exiftool.creator], filter(...)[] is not null and strings.icontains(filter(...)[], filter(attachments)[].domain.domain)) and not filter(...)[].domain.root_domain in ('pdf-tools.com') and not filter(...)[].url in ('https://gamma.app/?utm_source=made-with-gamma')) length_compare "3"
macro "all(filter(...)[].scan.url.urls)"
or
recipients.to[0].email.domain.valid eq "false"
sender.email.email cross_field_compare "recipients.to[0].email.email"
attachments length_compare "1"
beta.parse_exif func_call "beta.parse_exif(attachments[0]).page_count == 1"
sum func_call "sum([length(recipients.to), length(recipients.cc)]) == 1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
recipients.to[0].email.domain.valid | eq |
| field:"recipients.to[0].email.domain.valid" kind:eq value:"false" |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with specific author metadata
#Detects inbound messages containing PDF attachments where the EXIF metadata indicates the author or creator is 'Shelby Porter'.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type == "pdf")) >= 1
and any(filter(attachments, .file_type == "pdf"),
beta.parse_exif(.).author == "Shelby Porter"
or beta.parse_exif(.).creator == "Shelby Porter"
)
Detection logic
Scope: inbound message.
Detects inbound messages containing PDF attachments where the EXIF metadata indicates the author or creator is 'Shelby Porter'.
- inbound message
- length(filter(attachments, .file_type == 'pdf')) ≥ 1
any of
filter(attachments)where any holds:- beta.parse_exif(.).author is 'Shelby Porter'
- beta.parse_exif(.).creator is 'Shelby Porter'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
or
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).author == Shelby Porter"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).creator == Shelby Porter"
filter(attachments, .file_type == 'pdf') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with specific W-9 lure
#Detects PDF attachments containing W-9 related lures. This one is looking for signatures that have been observed across multiple samples.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("pdf_w9_signature_c003"))
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing W-9 related lures. This one is looking for signatures that have been observed across multiple samples.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('pdf_w9_signature_c003')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | pdf_w9_signature_c003 |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_w9_signature_c003"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with split QR code
#Detects PDF attachments containing split QR codes positioned close together, a technique used to evade detection while maintaining QR code functionality for credential theft.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, PDF, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
// yara rules match on "split" QR codes that are 290x290, 300x300, 370x370 and placed close to eachtoher in the PDF
strings.istarts_with(.name, 'Phishing_PDF_Split_QR_Code_Pair')
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing split QR codes positioned close together, a technique used to evade detection while maintaining QR code functionality for credential theft.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name starts with 'Phishing_PDF_Split_QR_Code_Pair'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.istarts_with.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.istarts_with | prefix | Phishing_PDF_Split_QR_Code_Pair |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name starts_with "Phishing_PDF_Split_QR_Code_Pair"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious document view lure
#Detects PDF attachments containing a title box designed to lure recipients into viewing a document, a common social engineering technique used to direct users to malicious content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches, .name == "pdf_view_doc_here_title_box")
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a title box designed to lure recipients into viewing a document, a common social engineering technique used to direct users to malicious content.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'pdf_view_doc_here_title_box'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | equals | pdf_view_doc_here_title_box |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "pdf_view_doc_here_title_box"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious HeadlessChrome metadata
#Detects PDF attachments created by HeadlessChrome with suspicious characteristics, including MD5-formatted HTML filenames or blank titles with Windows Skia/PDF producer, excluding legitimate Google Docs files.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_extension == "pdf"),
strings.icontains(beta.parse_exif(.).creator, "HeadlessChrome")
and beta.parse_exif(.).page_count == 1
and (
// MD5 filename, 32 hex chars and .html
(
regex.imatch(beta.parse_exif(.).title, '^[a-f0-9]{32}\.html$')
or
// about:blank and Windows HeadlessChrome
(
beta.parse_exif(.).title == "about:blank"
and strings.istarts_with(beta.parse_exif(.).producer, "Skia/PDF")
and strings.icontains(beta.parse_exif(.).creator, "Windows")
)
// cred theft intents on the message and Windows Headless Chrome
or (
any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence != "low"
)
and strings.istarts_with(beta.parse_exif(.).producer, "Skia/PDF")
and strings.icontains(beta.parse_exif(.).creator, "Windows")
)
)
and not strings.icontains(beta.parse_exif(.).producer, "Google Docs")
)
)
and not (
sender.email.domain.root_domain in (
"guardtek.net",
"gominis.com",
"aglgroup.com",
"truckerzoom.com"
)
and coalesce(headers.auth_summary.dmarc.pass, false)
)
Detection logic
Scope: inbound message.
Detects PDF attachments created by HeadlessChrome with suspicious characteristics, including MD5-formatted HTML filenames or blank titles with Windows Skia/PDF producer, excluding legitimate Google Docs files.
- inbound message
any of
filter(attachments)where all hold:- beta.parse_exif(.).creator contains 'HeadlessChrome'
- beta.parse_exif(.).page_count is 1
all of:
any of:
- beta.parse_exif(.).title matches '^[a-f0-9]{32}\\.html$'
all of:
- beta.parse_exif(.).title is 'about:blank'
- beta.parse_exif(.).producer starts with 'Skia/PDF'
- beta.parse_exif(.).creator contains 'Windows'
all of:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
- beta.parse_exif(.).producer starts with 'Skia/PDF'
- beta.parse_exif(.).creator contains 'Windows'
not:
- beta.parse_exif(.).producer contains 'Google Docs'
not:
all of:
- sender.email.domain.root_domain in ('guardtek.net', 'gominis.com', 'aglgroup.com', 'truckerzoom.com')
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.parse_exif, ml.nlu_classifier, regex.imatch, strings.icontains, strings.istarts_with.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
strings.icontains | substring | HeadlessChrome |
regex.imatch | regex | ^[a-f0-9]{32}\.html$ |
strings.istarts_with | prefix | Skia/PDF |
strings.icontains | substring | Windows |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
and
or
and
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"
beta.parse_exif(filter(attachments)[]).creator contains "Windows"
beta.parse_exif(filter(attachments)[]).producer starts_with "Skia/PDF"
and
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).title == about:blank"
beta.parse_exif(filter(attachments)[]).creator contains "Windows"
beta.parse_exif(filter(attachments)[]).producer starts_with "Skia/PDF"
beta.parse_exif(filter(attachments)[]).title regex_match "^[a-f0-9]{32}\\.html$"
not
beta.parse_exif(filter(attachments)[]).producer contains "Google Docs"
beta.parse_exif func_call "beta.parse_exif(filter(attachments)[]).page_count == 1"
beta.parse_exif(filter(attachments)[]).creator contains "HeadlessChrome"
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
sender.email.domain.root_domain in ["aglgroup.com", "gominis.com", "guardtek.net", "truckerzoom.com"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | in | aglgroup.com, gominis.com, guardtek.net, truckerzoom.com | excludes:sender.email.domain.root_domain |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious internal object reference identifier
#Detects inbound messages containing PDF attachments with a specific internal object reference identifier pattern, which may indicate a crafted or malicious PDF file.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
.depth == 0
and any(.scan.strings.strings,
strings.contains(., "[<C57237C22450666518136DE404118E5E>")
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing PDF attachments with a specific internal object reference identifier pattern, which may indicate a crafted or malicious PDF file.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .depth is 0
any of
.scan.strings.stringswhere:- . contains '[<C57237C22450666518136DE404118E5E>'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.contains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.contains | substring | [<C57237C22450666518136DE404118E5E> |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
any(file.explode(filter(attachments)).scan.strings.strings)
file.explode(filter(attachments)).scan.strings.strings contains "[<C57237C22450666518136DE404118E5E>"
file.explode(filter(attachments)[])[].depth eq "0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious language and redirect to suspicious file type
#Attached PDF contains credential theft language, and links to an open redirect to a suspicious file type. This has been observed in-the-wild as a Qakbot technique.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
length(.scan.url.urls) > 0
and any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft"
and .confidence in~ ("medium", "high")
)
and any(.scan.url.urls,
strings.icontains(ml.link_analysis(.).final_dom.display_text,
"Redirect Notice"
)
and (
strings.contains(ml.link_analysis(.).final_dom.display_text,
".zip"
)
or strings.contains(ml.link_analysis(.).final_dom.display_text,
".php"
)
)
)
)
)
Detection logic
Scope: inbound message.
Attached PDF contains credential theft language, and links to an open redirect to a suspicious file type. This has been observed in-the-wild as a Qakbot technique.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where all hold:- length(.scan.url.urls) > 0
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('medium', 'high')
any of
.scan.url.urlswhere all hold:- ml.link_analysis(.).final_dom.display_text contains 'Redirect Notice'
any of:
- ml.link_analysis(.).final_dom.display_text contains '.zip'
- ml.link_analysis(.).final_dom.display_text contains '.php'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, strings.contains, strings.icontains.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | member | medium |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | member | high |
strings.icontains | substring | Redirect Notice |
strings.contains | substring | .zip |
strings.contains | substring | .php |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
and
or
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).final_dom.display_text contains ".php"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).final_dom.display_text contains ".zip"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).final_dom.display_text contains "Redirect Notice"
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"
file.explode(attachments[])[].scan.url.urls length_compare "0"
attachments.file_type eq "pdf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious link and action-oriented language
#Detects PDF attachments containing a single link that leads to pages with language prompting users to view, review, or read documents, accounts, or business-related content such as bids, proposals, agreements, or contracts.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(filter(attachments, .file_type == "pdf")) >= 1
and any(attachments,
.file_type == "pdf"
and beta.parse_exif(.).page_count == 1
and any(file.explode(.),
.depth == 0
// reduce fps by limiting the length to a single link
and length(.scan.url.urls) == 1
and any(filter(.scan.url.urls,
// remove mailto: links
not strings.istarts_with(.url, 'mailto:')
and not strings.istarts_with(.url, 'email:')
// remove links found in exiftool output
and not (
..scan.exiftool.producer is not null
and strings.icontains(..scan.exiftool.producer,
.domain.domain
)
)
// remove links found in exiftool output
and not (
..scan.exiftool.creator is not null
and strings.icontains(..scan.exiftool.creator,
.domain.domain
)
)
and not .domain.root_domain in ('pdf-tools.com')
),
(
200 <= ml.link_analysis(.).status_code < 300
and length(ml.link_analysis(.).final_dom.links) < 100
and any(ml.link_analysis(.).final_dom.links,
.href_url.domain.root_domain != ..domain.root_domain
and regex.icontains(.display_text,
'\b(?:(?:re)?view|see|read|click\s+(?:here\s+)?to)[\t\x20]*(?:\S+[\t\x20]*){0,3}[\t\x20]*(?:document|message|now|proceed)',
'\b(?:request|review)\b.{1,5}\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\b',
)
)
)
or (
200 <= ml.link_analysis(.).status_code < 300
and length(ml.link_analysis(.).final_dom.display_text) < 1050
and regex.icontains(ml.link_analysis(.).final_dom.display_text,
'\b(?:(?:re)?view|see|read|click\s+(?:here\s+)?to)[\t\x20]*(?:\S+[\t\x20]*){0,3}[\t\x20]*(?:document|message|now|proceed)',
'\b(?:request|review)\b.{1,5}\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\b'
)
// a common fp in the .au for a payment system
and not strings.icontains(ml.link_analysis(.).final_dom.display_text,
'View Podium Message'
)
)
// the title contains high confidence indicators
or any(html.xpath(ml.link_analysis(.).final_dom,
'//title'
).nodes,
strings.icontains(.raw, 'Secure Document')
)
)
)
)
Detection logic
Scope: inbound message.
Detects PDF attachments containing a single link that leads to pages with language prompting users to view, review, or read documents, accounts, or business-related content such as bids, proposals, agreements, or contracts.
- inbound message
- length(filter(attachments, .file_type == 'pdf')) ≥ 1
any of
attachmentswhere all hold:- .file_type is 'pdf'
- beta.parse_exif(.).page_count is 1
any of
file.explode(.)where all hold:- .depth is 0
- length(.scan.url.urls) is 1
any of
filter(.scan.url.urls)where any holds:all of:
all of:
- ml.link_analysis(.).status_code ≥ 200
- ml.link_analysis(.).status_code < 300
- length(ml.link_analysis(.).final_dom.links) < 100
any of
ml.link_analysis(.).final_dom.linkswhere all hold:- .href_url.domain.root_domain is not .domain.root_domain
.display_text matches any of 2 patterns
\b(?:(?:re)?view|see|read|click\s+(?:here\s+)?to)[\t\x20]*(?:\S+[\t\x20]*){0,3}[\t\x20]*(?:document|message|now|proceed)\b(?:request|review)\b.{1,5}\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\b
all of:
all of:
- ml.link_analysis(.).status_code ≥ 200
- ml.link_analysis(.).status_code < 300
- length(ml.link_analysis(.).final_dom.display_text) < 1050
ml.link_analysis(.).final_dom.display_text matches any of 2 patterns
\b(?:(?:re)?view|see|read|click\s+(?:here\s+)?to)[\t\x20]*(?:\S+[\t\x20]*){0,3}[\t\x20]*(?:document|message|now|proceed)\b(?:request|review)\b.{1,5}\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\b
not:
- ml.link_analysis(.).final_dom.display_text contains 'View Podium Message'
any of
html.xpath(ml.link_analysis(.).final_dom, '//title').nodeswhere:- .raw contains 'Secure Document'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode, html.xpath, ml.link_analysis, regex.icontains, strings.icontains, strings.istarts_with.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | \b(?:(?:re)?view|see|read|click\s+(?:here\s+)?to)[\t\x20]*(?:\S+[\t\x20]*){0,3}[\t\x20]*(?:document|message|now|proceed) |
regex.icontains | regex | \b(?:request|review)\b.{1,5}\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\b |
strings.icontains | substring | Secure Document |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(filter(file.explode(attachments).scan.url.urls))
or
and
any(ml.link_analysis(filter(file.explode(attachments).scan.url.urls)).final_dom.links)
and
or
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.links[].display_text regex_match "\\b(?:(?:re)?view|see|read|click\\s+(?:here\\s+)?to)[\\t\\x20]*(?:\\S+[\\t\\x20]*){0,3}[\\t\\x20]*(?:document|message|now|proceed)"
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.links[].display_text regex_match "\\b(?:request|review)\\b.{1,5}\\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\\b"
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.links[].href_url.domain.root_domain cross_field_compare "filter(file.explode(attachments[])[].scan.url.urls)[].domain.root_domain"
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).status_code < 300"
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).status_code >= 200"
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.links length_compare "100"
and
not
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.display_text contains "View Podium Message"
or
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.display_text regex_match "\\b(?:(?:re)?view|see|read|click\\s+(?:here\\s+)?to)[\\t\\x20]*(?:\\S+[\\t\\x20]*){0,3}[\\t\\x20]*(?:document|message|now|proceed)"
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.display_text regex_match "\\b(?:request|review)\\b.{1,5}\\b(?:bid|proposal|agreement|portfolio|contract|settlement|invoice)\\b"
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).status_code < 300"
ml.link_analysis func_call "ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).status_code >= 200"
ml.link_analysis(filter(file.explode(attachments[])[].scan.url.urls)[]).final_dom.display_text length_compare "1050"
any(html.xpath(ml.link_analysis(filter(file.explode(attachments).scan.url.urls)).final_dom, '//title').nodes)
html.xpath(ml.link_analysis(filter(file.explode(attachments).scan.url.urls)).final_dom, '//title').nodes.raw contains "Secure Document"
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.url.urls length_compare "1"
attachments.file_type eq "pdf"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
filter(attachments, .file_type == 'pdf') length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with suspicious view document characteristics
#PDF attachment contains suspicious characteristics commonly associated with document viewing lures, as detected by YARA pattern matching.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name == "view_document_pdf_characteristics"
)
)
)
Detection logic
Scope: inbound message.
PDF attachment contains suspicious characteristics commonly associated with document viewing lures, as detected by YARA pattern matching.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'view_document_pdf_characteristics'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | equals | view_document_pdf_characteristics |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "view_document_pdf_characteristics"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PDF with W-9 form indicators
#Detects inbound messages containing PDF attachments that match structural or signature patterns consistent with specific W-9 tax lure activity sets.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | PDF, Social engineering, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "pdf"),
any(file.explode(.),
any(.scan.yara.matches,
.name in ("w9_c001_signatures", "w9_c001_structure")
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing PDF attachments that match structural or signature patterns consistent with specific W-9 tax lure activity sets.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('w9_c001_signatures', 'w9_c001_structure')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | w9_c001_signatures |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | w9_c001_structure |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name in ["w9_c001_signatures", "w9_c001_structure"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Potential sandbox evasion in Office file
#Scans attached files with known Office file extension, and alerts on the presence of strings indicative of sandbox evasion checks. Malicious code may carry out checks against the local host (e.g. running processes, disk size, domain-joined status) before running its final payload.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and any(file.explode(.),
1 of (
any(.scan.strings.strings,
strings.ilike(., "*Win32_Processor*")
),
any(.scan.strings.strings,
strings.ilike(., "*Win32_LogicalDisk*")
),
any(.scan.strings.strings,
strings.ilike(., "*Win32_ComputerSystem*")
),
any(.scan.strings.strings,
strings.ilike(., "*Win32_Process*")
),
any(.scan.strings.strings,
strings.ilike(., "*LDAP://RootDSE*")
)
)
)
)
Detection logic
Scope: inbound message.
Scans attached files with known Office file extension, and alerts on the presence of strings indicative of sandbox evasion checks. Malicious code may carry out checks against the local host (e.g. running processes, disk size, domain-joined status) before running its final payload.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
any of
file.explode(.)where:at least 1 of:
any of
.scan.strings.stringswhere:- . matches '*Win32_Processor*'
any of
.scan.strings.stringswhere:- . matches '*Win32_LogicalDisk*'
any of
.scan.strings.stringswhere:- . matches '*Win32_ComputerSystem*'
any of
.scan.strings.stringswhere:- . matches '*Win32_Process*'
any of
.scan.strings.stringswhere:- . matches '*LDAP://RootDSE*'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode, strings.ilike. Reference lists: $file_extensions_macros.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
strings.ilike | substring | *Win32_Processor* |
strings.ilike | substring | *Win32_LogicalDisk* |
strings.ilike | substring | *Win32_ComputerSystem* |
strings.ilike | substring | *Win32_Process* |
strings.ilike | substring | *LDAP://RootDSE* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "LDAP://RootDSE"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Win32_ComputerSystem"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Win32_LogicalDisk"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Win32_Process"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "Win32_Processor"
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PowerPoint with suspicious hyperlink
#Attached PowerPoint contains a suspicious hyperlink that can execute arbitrary code.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_extension in~ ("ppt", "pptx"))
and any(file.explode(.),
any(.scan.exiftool.fields,
.key == "Hyperlinks"
and (
4 of (
strings.ilike(.value, "*[Convert]::ToChar*"),
strings.ilike(.value, "*vbs*"),
strings.ilike(.value, "*[IO.File]::Create*"),
strings.ilike(.value, "*[IO.File]::Exists*"),
strings.ilike(.value,
"*[io.FileOPtions]::DeleteOnClose*"
),
strings.ilike(.value, "*Net.WebClient*"),
strings.ilike(.value, "*dll*"),
)
)
)
)
)
Detection logic
Scope: inbound message.
Attached PowerPoint contains a suspicious hyperlink that can execute arbitrary code.
- inbound message
any of
attachmentswhere all hold:- .file_extension in ('ppt', 'pptx')
any of
file.explode(.)where:any of
.scan.exiftool.fieldswhere all hold:- .key is 'Hyperlinks'
at least 4 of 7: .value matches any of 7 patterns
*[Convert]::ToChar**vbs**[IO.File]::Create**[IO.File]::Exists**[io.FileOPtions]::DeleteOnClose**Net.WebClient**dll*
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ppt |
attachments[].file_extension | member | pptx |
file.explode(attachments[])[].scan.exiftool.fields[].key | equals | Hyperlinks |
strings.ilike | substring | *[Convert]::ToChar* |
strings.ilike | substring | *vbs* |
strings.ilike | substring | *[IO.File]::Create* |
strings.ilike | substring | *[IO.File]::Exists* |
strings.ilike | substring | *[io.FileOPtions]::DeleteOnClose* |
strings.ilike | substring | *Net.WebClient* |
strings.ilike | substring | *dll* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.exiftool.fields)
and
or
file.explode(attachments[])[].scan.exiftool.fields[].value match "Net.WebClient"
file.explode(attachments[])[].scan.exiftool.fields[].value match "[Convert]::ToChar"
file.explode(attachments[])[].scan.exiftool.fields[].value match "[IO.File]::Create"
file.explode(attachments[])[].scan.exiftool.fields[].value match "[IO.File]::Exists"
file.explode(attachments[])[].scan.exiftool.fields[].value match "[io.FileOPtions]::DeleteOnClose"
file.explode(attachments[])[].scan.exiftool.fields[].value match "dll"
file.explode(attachments[])[].scan.exiftool.fields[].value match "vbs"
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Hyperlinks"
attachments.file_extension in ["ppt", "pptx"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: PowerShell content
#Recursively scans files and archives to detect PowerShell content. While scripts are often blocked by mail filtering, alternative file formats and archived content may be employed to bypass such controls.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ (
// PowerShell related file extensions
"ps1",
"ps1xml",
"psm1",
"psd1",
"pssc",
"psrc",
"cdxml",
"ps2",
"ps2xml",
"psc2",
)
or .file_extension in~ $file_extensions_common_archives
)
and any(file.explode(.),
.file_extension in~ (
"ps1",
"ps1xml",
"psm1",
"psd1",
"pssc",
"psrc",
"cdxml",
"ps2",
"ps2xml",
"psc2",
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect PowerShell content. While scripts are often blocked by mail filtering, alternative file formats and archived content may be employed to bypass such controls.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in ('ps1', 'ps1xml', 'psm1', 'psd1', 'pssc', 'psrc', 'cdxml', 'ps2', 'ps2xml', 'psc2')
- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension in ('ps1', 'ps1xml', 'psm1', 'psd1', 'pssc', 'psrc', 'cdxml', 'ps2', 'ps2xml', 'psc2')
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (20)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | ps1 |
attachments[].file_extension | member | ps1xml |
attachments[].file_extension | member | psm1 |
attachments[].file_extension | member | psd1 |
attachments[].file_extension | member | pssc |
attachments[].file_extension | member | psrc |
attachments[].file_extension | member | cdxml |
attachments[].file_extension | member | ps2 |
attachments[].file_extension | member | ps2xml |
attachments[].file_extension | member | psc2 |
file.explode(attachments[])[].file_extension | member | ps1 |
file.explode(attachments[])[].file_extension | member | ps1xml |
8 more
file.explode(attachments[])[].file_extension | member | psm1 |
file.explode(attachments[])[].file_extension | member | psd1 |
file.explode(attachments[])[].file_extension | member | pssc |
file.explode(attachments[])[].file_extension | member | psrc |
file.explode(attachments[])[].file_extension | member | cdxml |
file.explode(attachments[])[].file_extension | member | ps2 |
file.explode(attachments[])[].file_extension | member | ps2xml |
file.explode(attachments[])[].file_extension | member | psc2 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.file_extension in ["cdxml", "ps1", "ps1xml", "ps2", "ps2xml", "psc2", "psd1", "psm1", "psrc", "pssc"]
macro "attachments[].file_extension in file_extensions_common_archives"
any(file.explode(attachments))
file.explode(attachments).file_extension in ["cdxml", "ps1", "ps1xml", "ps2", "ps2xml", "psc2", "psd1", "psm1", "psrc", "pssc"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: QR code link with base64-encoded recipient address
#Detects when an image or macro attachment contains QR codes that, when scanned, lead to URLs containing the recipient's email address. This tactic is used to uniquely track or target specific recipients and serve tailored credential phishing pages.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Image as content, Social engineering, Evasion, PDF, Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 1 of (
any(ml.nlu_classifier(subject.subject).intents,
.name == "cred_theft" and .confidence == "high"
),
body.current_thread.text is null,
any($org_slds, strings.icontains(sender.display_name, .))
)
and any(attachments,
(
.file_type in $file_types_images
or .file_extension in $file_extensions_macros
or .file_type == "pdf"
)
and any(file.explode(.),
any(recipients.to,
.email.domain.valid
and any(beta.scan_base64(..scan.qr.url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
)
Detection logic
Scope: inbound message.
Detects when an image or macro attachment contains QR codes that, when scanned, lead to URLs containing the recipient's email address. This tactic is used to uniquely track or target specific recipients and serve tailored credential phishing pages.
- inbound message
at least 1 of:
any of
ml.nlu_classifier(subject.subject).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
- body.current_thread.text is missing
any of
$org_sldswhere:- strings.icontains(sender.display_name)
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_extension in $file_extensions_macros
- .file_type is 'pdf'
any of
file.explode(.)where:any of
recipients.towhere all hold:- .email.domain.valid
any of
beta.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
Inspects: attachments[].file_extension, attachments[].file_type, body.current_thread.text, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.display_name, subject.subject, type.inbound. Sensors: beta.scan_base64, file.explode, ml.nlu_classifier, strings.icontains. Reference lists: $file_extensions_macros, $file_types_images, $org_slds.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(subject.subject).intents[].name | equals | cred_theft |
ml.nlu_classifier(subject.subject).intents[].confidence | equals | high |
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(recipients.to)
and
any(beta.scan_base64(file.explode(attachments).scan.qr.url.url))
strings.icontains func_call "strings.icontains(beta.scan_base64(file.explode(attachments[])[].scan.qr.url.url)[])"
recipients.to.email.domain.valid eq "true"
or
attachments.file_type eq "pdf"
macro "attachments[].file_extension in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
or
any(ml.nlu_classifier(subject.subject).intents)
and
ml.nlu_classifier(subject.subject).intents.confidence eq "high"
ml.nlu_classifier(subject.subject).intents.name eq "cred_theft"
any($org_slds)
strings.icontains func_call "strings.icontains(sender.display_name)"
body.current_thread.text is_null
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: QR code with credential phishing indicators
#Detects messages with between 1-3 attachments containing a QR code with suspicious credential theft indicators, such as: LinkAnalysis credential phishing conclusion, decoded QR code url traverses suspicious infrastructure, the final destination is in URLhaus, decoded URL downloads a zip or executable, leverages URL shorteners, known QR abused openredirects, and more.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
1 <= length(attachments) < 3
or (
// if there are more than three attachments
3 <= length(attachments) < 20
// there are only pngs and pdf/docx
and length(distinct(map(attachments, .file_extension))) == 2
and all(distinct(map(attachments, .file_extension)),
. in ('png', 'pdf', 'docx')
)
and (
// multiple attachments mention common brands or other common common filenames
(
length(filter(attachments,
strings.icontains(.file_name, 'adobe')
or strings.icontains(.file_name, 'office')
or strings.icontains(.file_name, 'appstore')
or strings.icontains(.file_name, 'google')
or strings.icontains(.file_name, 'padlock')
or regex.icontains(.file_name, '\bdoc\b')
)
) > 3
)
// the attachment name contains the SLD of a recipient
or any(filter(attachments, .file_extension in ('pdf', 'docx')),
any(filter(recipients.to, .email.domain.valid),
strings.icontains(..file_name, .email.domain.sld)
)
)
)
)
)
// Inspects image attachments for QR codes
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"
and not .scan.qr.url.domain.domain == "geico.app.link"
and (
// pass the QR URL to LinkAnalysis
any([ml.link_analysis(.scan.qr.url)],
.credphish.disposition == "phishing"
// any routing traverses via $suspicious_tld list
or any(.redirect_history, .domain.tld in $suspicious_tlds)
// effective destination in $suspicious_tld list
or .effective_url.domain.tld in $suspicious_tlds
// or the effective destination domain is in $abuse_ch_urlhaus_domains_trusted_reporters
or .effective_url.domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters
// or any files downloaded are zips or executables
or any(.files_downloaded,
.file_extension in $file_extensions_common_archives
or .file_extension in $file_extensions_executables
)
)
or (
// or the QR code's root domain is a url_shortener
.scan.qr.url.domain.root_domain in $url_shorteners
or (
.scan.qr.url.domain.root_domain in $social_landing_hosts
and (
not (
any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "benign"
)
or any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "disclaimer"
)
)
or not any(attachments,
any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "benign"
)
)
)
// the QR code contains the email address of a recipient
or (
any(filter(recipients.to, .email.domain.valid),
strings.icontains(..scan.qr.url.url, .email.email)
)
)
)
// exclude google maps
and not strings.starts_with(.scan.qr.url.url,
'https://goo.gl/maps'
)
and not strings.starts_with(.scan.qr.url.url,
'https://maps.app.goo.gl'
)
)
)
// the QR code url is a bing open redirect
or (
.scan.qr.url.domain.root_domain == 'bing.com'
and .scan.qr.url.path =~ '/ck/a'
)
// QR code contains non ascii chars
or regex.contains(.scan.qr.url.url, '[^\x00-\x7F]')
or (
(
// usap-dc open redirect
.scan.qr.url.domain.root_domain == "usap-dc.org"
and .scan.qr.url.path =~ "/tracker"
and strings.starts_with(.scan.qr.url.query_params,
"type=dataset&url=http"
)
)
// the QR code contains the email address of a recipient
// allowing for base64 encoded variants
or (
any(filter(recipients.to, .email.domain.valid),
strings.icontains(..scan.qr.url.url, .email.email)
or any(strings.scan_base64(..scan.qr.url.url,
ignore_padding=true
),
strings.icontains(., ..email.email)
)
or any(strings.scan_base64(..scan.qr.url.fragment,
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
)
)
)
)
)
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 (
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.
Detects messages with between 1-3 attachments containing a QR code with suspicious credential theft indicators, such as: LinkAnalysis credential phishing conclusion, decoded QR code url traverses suspicious infrastructure, the final destination is in URLhaus, decoded URL downloads a zip or executable, leverages URL shorteners, known QR abused openredirects, and more.
- inbound message
any of:
all of:
- length(attachments) ≥ 1
- length(attachments) < 3
all of:
all of:
- length(attachments) ≥ 3
- length(attachments) < 20
- length(distinct(map(attachments, .file_extension))) is 2
all of
distinct(...)where:- . in ('png', 'pdf', 'docx')
any of:
- length(filter(attachments, strings.icontains(.file_name, 'adobe') or strings.icontains(.file_name, 'office') or strings.icontains(.file_name, 'appstore') or strings.icontains(.file_name, 'google') or strings.icontains(.file_name, 'padlock') or regex.icontains(.file_name, '\\bdoc\\b'))) > 3
any of
filter(attachments)where:any of
filter(recipients.to)where:- strings.icontains(.file_name)
any of
attachmentswhere 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 all hold:- .scan.qr.type is 'url'
not:
- .scan.qr.url.domain.domain is 'geico.app.link'
any of:
any of
[ml.link_analysis(.scan.qr.url)]where any holds:- .credphish.disposition is 'phishing'
any of
.redirect_historywhere:- .domain.tld in $suspicious_tlds
- .effective_url.domain.tld in $suspicious_tlds
- .effective_url.domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters
any of
.files_downloadedwhere any holds:- .file_extension in $file_extensions_common_archives
- .file_extension in $file_extensions_executables
any of:
- .scan.qr.url.domain.root_domain in $url_shorteners
all of:
- .scan.qr.url.domain.root_domain in $social_landing_hosts
any of:
none of:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name is 'benign'
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name is 'disclaimer'
not:
any of
attachmentswhere:any of
file.explode(.)where:any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere:- .name is 'benign'
any of
filter(recipients.to)where:- strings.icontains(.scan.qr.url.url)
not:
- .scan.qr.url.url starts with 'https://goo.gl/maps'
not:
- .scan.qr.url.url starts with 'https://maps.app.goo.gl'
all of:
- .scan.qr.url.domain.root_domain is 'bing.com'
- .scan.qr.url.path is '/ck/a'
- .scan.qr.url.url matches '[^\\x00-\\x7F]'
any of:
all of:
- .scan.qr.url.domain.root_domain is 'usap-dc.org'
- .scan.qr.url.path is '/tracker'
- .scan.qr.url.query_params starts with 'type=dataset&url=http'
any of
filter(recipients.to)where any holds:- strings.icontains(.scan.qr.url.url)
any of
strings.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
any of
strings.scan_base64(.scan.qr.url.fragment)where:- strings.icontains(.)
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
all of:
- sender.email.domain.domain in $org_domains
not:
- coalesce(headers.auth_summary.dmarc.pass)
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.valid, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender_email, regex.contains, regex.icontains, strings.icontains, strings.scan_base64, strings.starts_with. Reference lists: $abuse_ch_urlhaus_domains_trusted_reporters, $file_extensions_common_archives, $file_extensions_executables, $file_extensions_macros, $file_types_images, $high_trust_sender_root_domains, $org_domains, $social_landing_hosts, $suspicious_tlds, $url_shorteners.
Indicators matched (20)
| Field | Match | Value |
|---|---|---|
distinct(...)[] | member | png |
distinct(...)[] | member | pdf |
distinct(...)[] | member | docx |
strings.icontains | substring | adobe |
strings.icontains | substring | office |
strings.icontains | substring | appstore |
strings.icontains | substring | google |
strings.icontains | substring | padlock |
regex.icontains | regex | \bdoc\b |
attachments[].file_extension | member | pdf |
attachments[].file_extension | member | docx |
attachments[].file_type | equals | pdf |
8 more
file.explode(attachments[])[].scan.qr.type | equals | url |
[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].credphish.disposition | equals | phishing |
file.explode(attachments[])[].scan.qr.url.domain.root_domain | equals | bing.com |
file.explode(attachments[])[].scan.qr.url.path | equals | /ck/a |
regex.contains | regex | [^\x00-\x7F] |
file.explode(attachments[])[].scan.qr.url.domain.root_domain | equals | usap-dc.org |
file.explode(attachments[])[].scan.qr.url.path | equals | /tracker |
strings.starts_with | prefix | type=dataset&url=http |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
and
or
not
any(attachments)
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 "benign"
not
or
any(ml.nlu_classifier(body.current_thread.text).entities)
ml.nlu_classifier(body.current_thread.text).entities.name eq "disclaimer"
any(ml.nlu_classifier(body.current_thread.text).intents)
ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
any(filter(recipients.to))
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.url.url)"
not
file.explode(attachments[])[].scan.qr.url.url starts_with "https://goo.gl/maps"
not
file.explode(attachments[])[].scan.qr.url.url starts_with "https://maps.app.goo.gl"
macro "file.explode(attachments[])[].scan.qr.url.domain.root_domain in social_landing_hosts"
any([ml.link_analysis(file.explode(attachments).scan.qr.url)])
or
any([ml.link_analysis(file.explode(attachments).scan.qr.url)].files_downloaded)
or
macro "[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].files_downloaded[].file_extension in file_extensions_common_archives"
macro "[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].files_downloaded[].file_extension in file_extensions_executables"
any([ml.link_analysis(file.explode(attachments).scan.qr.url)].redirect_history)
macro "[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].redirect_history[].domain.tld in suspicious_tlds"
[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].credphish.disposition eq "phishing"
macro "[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].effective_url.domain.root_domain in abuse_ch_urlhaus_domains_trusted_reporters"
macro "[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].effective_url.domain.tld in suspicious_tlds"
any(filter(recipients.to))
or
any(strings.scan_base64(file.explode(attachments).scan.qr.url.fragment))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(attachments[])[].scan.qr.url.fragment)[])"
any(strings.scan_base64(file.explode(attachments).scan.qr.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(attachments[])[].scan.qr.url.url)[])"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.url.url)"
and
file.explode(attachments[])[].scan.qr.url.domain.root_domain eq "bing.com"
file.explode(attachments[])[].scan.qr.url.path eq "/ck/a"
and
file.explode(attachments[])[].scan.qr.url.domain.root_domain eq "usap-dc.org"
file.explode(attachments[])[].scan.qr.url.path eq "/tracker"
file.explode(attachments[])[].scan.qr.url.query_params starts_with "type=dataset&url=http"
file.explode(attachments[])[].scan.qr.url.url regex_match "[^\\x00-\\x7F]"
macro "file.explode(attachments[])[].scan.qr.url.domain.root_domain in url_shorteners"
not
file.explode(attachments[])[].scan.qr.url.domain.domain eq "geico.app.link"
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"
or
and
or
any(filter(attachments))
any(filter(recipients.to))
strings.icontains func_call "strings.icontains(filter(attachments)[].file_name)"
filter(attachments, strings.icontains(.file_name, 'adobe') or strings.icontains(.file_name, 'office') or strings.icontains(.file_name, 'appstore') or strings.icontains(.file_name, 'google') or strings.icontains(.file_name, 'padlock') or regex.icontains(.file_name, '\\bdoc\\b')) length_compare "3"
attachments length_compare "20"
attachments length_compare "3"
distinct(map(attachments, .file_extension)) length_compare "2"
macro "all(distinct(...))"
and
attachments length_compare "1"
attachments length_compare "3"
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"
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)"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: QR code with encoded recipient targeting and redirect indicators
#Detects QR codes in attachments that contain the recipient's email address (either plaintext or base64 encoded) and redirect through suspicious URI structures commonly associated with Kratos/SneakyLog redirection services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Evasion, Image as content, Open redirect |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// QR code detection in attachments
and any(attachments,
(
// Office documents
.file_extension in $file_extensions_macros
and any(file.explode(.),
.scan.qr.type == "url"
// QR code URL contains recipient's email (targeting indicator)
and any(recipients.to,
.email.domain.valid
and (
// Plaintext email address in URL
strings.icontains(..scan.qr.url.url, .email.email)
// OR base64 encoded email address
or any(strings.scan_base64(..scan.qr.url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
// URI Struct for Common Kratos/SneakyLog Redir
and regex.contains(.scan.qr.url.url,
'\.(?:c(?:ompany|you)|sbs)(?:[$#]|\?a=)'
)
)
)
or (
// pdf or images
(
.file_type == "pdf" or .file_type in $file_types_images
)
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
and any(beta.scan_qr(.).items,
.type is not null
and regex.contains(.url.url,
'\.(?:c(?:ompany|you)|sbs)(?:[$#]|\?a=)'
)
)
)
)
Detection logic
Scope: inbound message.
Detects QR codes in attachments that contain the recipient's email address (either plaintext or base64 encoded) and redirect through suspicious URI structures commonly associated with Kratos/SneakyLog redirection services.
- inbound message
any of
attachmentswhere any holds:all of:
- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.scan.qr.url.url)
any of
strings.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
- .scan.qr.url.url matches '\\.(?:c(?:ompany|you)|sbs)(?:[$#]|\\?a=)'
all of:
any of:
- .file_type is 'pdf'
- .file_type in $file_types_images
any of
beta.scan_qr(.).itemswhere all hold:- .type is set
- .url.url matches '\\.(?:c(?:ompany|you)|sbs)(?:[$#]|\\?a=)'
Inspects: attachments[].file_extension, attachments[].file_type, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: beta.scan_qr, file.explode, regex.contains, strings.icontains, strings.scan_base64. Reference lists: $file_extensions_macros, $file_types_images.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].scan.qr.type | equals | url |
regex.contains | regex | \.(?:c(?:ompany|you)|sbs)(?:[$#]|\?a=) |
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
and
any(recipients.to)
and
or
any(strings.scan_base64(file.explode(attachments).scan.qr.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(attachments[])[].scan.qr.url.url)[])"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.url.url)"
recipients.to.email.domain.valid eq "true"
file.explode(attachments[])[].scan.qr.type eq "url"
file.explode(attachments[])[].scan.qr.url.url regex_match "\\.(?:c(?:ompany|you)|sbs)(?:[$#]|\\?a=)"
macro "attachments[].file_extension in file_extensions_macros"
and
any(beta.scan_qr(attachments).items)
and
beta.scan_qr(attachments[]).items[].type is_not_null
beta.scan_qr(attachments[]).items[].url.url regex_match "\\.(?:c(?:ompany|you)|sbs)(?:[$#]|\\?a=)"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_types_images"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: QR code with recipient targeting and special characters
#Detects messages with QR code in attachments containing 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).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(attachments,
(
// Office documents
.file_extension in $file_extensions_macros
and any(file.explode(.),
.scan.qr.type == "url"
// QR code URL contains recipient's email (targeting indicator)
and any(recipients.to,
.email.domain.valid
and (
// Plaintext email address in URL
strings.icontains(..scan.qr.url.url, .email.email)
// OR base64 encoded email address
or any(strings.scan_base64(..scan.qr.url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
// a single path
and strings.count(.scan.qr.url.path, '/') == 2
and (
(
(
strings.contains(.scan.qr.url.path, '/$')
or strings.contains(.scan.qr.url.path, '/*')
or strings.contains(.scan.qr.url.path, '/#')
)
// subdomain should contain num{3}alpha or alphanum{3}
and regex.icontains(.scan.qr.url.domain.subdomain,
'^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)'
)
// url path should contain num{3}alpha or alphanum{3}
and regex.icontains(.scan.qr.url.path,
'\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/'
)
)
or (
// special char in the path
(
strings.contains(.scan.qr.url.path, '!')
or strings.contains(.scan.qr.url.path, '@')
)
and (
strings.contains(.scan.qr.url.path, '/$')
or strings.contains(.scan.qr.url.path, '/*')
or strings.contains(.scan.qr.url.path, '/#')
// hex dollar sign
or strings.icontains(.scan.qr.url.path, '%24')
// hex star
or strings.icontains(.scan.qr.url.path, '%2A')
// hex pound
or strings.icontains(.scan.qr.url.path, '%23')
)
// ensure expected ordering
and regex.icontains(.scan.qr.url.url,
'[!@].*(?:[$*]|%2[A43])'
)
)
)
)
)
or (
// pdf or images
(
.file_type == "pdf" or .file_type in $file_types_images
)
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
and any(beta.scan_qr(.).items,
.type is not null
// a single path
and strings.count(.url.path, '/') == 2
and (
(
(
strings.contains(.url.path, '/$')
or strings.contains(.url.path, '/*')
or strings.contains(.url.path, '/#')
)
// subdomain should contain num{3}alpha or alphanum{3}
and regex.icontains(.url.domain.subdomain,
'^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)'
)
// url path should contain num{3}alpha or alphanum{3}
and regex.icontains(.url.path,
'\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/'
)
)
or (
// special char in the path
(
strings.contains(.url.path, '!')
or strings.contains(.url.path, '@')
)
and (
strings.contains(.url.path, '/$')
or strings.contains(.url.path, '/*')
or strings.contains(.url.path, '/#')
// hex dollar sign
or strings.icontains(.url.path, '%24')
// hex star
or strings.icontains(.url.path, '%2A')
// hex pound
or strings.icontains(.url.path, '%23')
)
// ensure expected ordering
and regex.icontains(.url.url, '[!@].*(?:[$*]|%2[A43])')
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects messages with QR code in attachments containing 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.
- inbound message
- length(recipients.to) is 1
- recipients.to[0].email.domain.valid
any of
attachmentswhere any holds:all of:
- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.scan.qr.url.url)
any of
strings.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
- strings.count(.scan.qr.url.path, '/') is 2
any of:
all of:
any of:
- .scan.qr.url.path contains '/$'
- .scan.qr.url.path contains '/*'
- .scan.qr.url.path contains '/#'
- .scan.qr.url.domain.subdomain matches '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)'
- .scan.qr.url.path matches '\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/'
all of:
any of:
- .scan.qr.url.path contains '!'
- .scan.qr.url.path contains '@'
.scan.qr.url.path contains any of 6 patterns
/$/*/#%24%2A%23
- .scan.qr.url.url matches '[!@].*(?:[$*]|%2[A43])'
all of:
any of:
- .file_type is 'pdf'
- .file_type in $file_types_images
any of
beta.scan_qr(.).itemswhere all hold:- .type is set
- strings.count(.url.path, '/') is 2
any of:
all of:
any of:
- .url.path contains '/$'
- .url.path contains '/*'
- .url.path contains '/#'
- .url.domain.subdomain matches '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)'
- .url.path matches '\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/'
all of:
any of:
- .url.path contains '!'
- .url.path contains '@'
.url.path contains any of 6 patterns
/$/*/#%24%2A%23
- .url.url matches '[!@].*(?:[$*]|%2[A43])'
Inspects: attachments[].file_extension, attachments[].file_type, recipients.to, recipients.to[0].email.domain.valid, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: beta.scan_qr, file.explode, regex.icontains, strings.contains, strings.count, strings.icontains, strings.scan_base64. Reference lists: $file_extensions_macros, $file_types_images.
Indicators matched (13)
| Field | Match | Value |
|---|---|---|
file.explode(attachments[])[].scan.qr.type | equals | url |
strings.contains | substring | /$ |
strings.contains | substring | /* |
strings.contains | substring | /# |
regex.icontains | regex | ^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.) |
regex.icontains | regex | \/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/ |
strings.contains | substring | ! |
strings.contains | substring | @ |
strings.icontains | substring | %24 |
strings.icontains | substring | %2A |
strings.icontains | substring | %23 |
regex.icontains | regex | [!@].*(?:[$*]|%2[A43]) |
1 more
attachments[].file_type | equals | pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(file.explode(attachments))
and
any(recipients.to)
and
or
any(strings.scan_base64(file.explode(attachments).scan.qr.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(attachments[])[].scan.qr.url.url)[])"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.url.url)"
recipients.to.email.domain.valid eq "true"
or
and
or
file.explode(attachments[])[].scan.qr.url.path contains "!"
file.explode(attachments[])[].scan.qr.url.path contains "@"
or
file.explode(attachments[])[].scan.qr.url.path contains "%23"
file.explode(attachments[])[].scan.qr.url.path contains "%24"
file.explode(attachments[])[].scan.qr.url.path contains "%2A"
file.explode(attachments[])[].scan.qr.url.path contains "/#"
file.explode(attachments[])[].scan.qr.url.path contains "/$"
file.explode(attachments[])[].scan.qr.url.path contains "/*"
file.explode(attachments[])[].scan.qr.url.url regex_match "[!@].*(?:[$*]|%2[A43])"
and
or
file.explode(attachments[])[].scan.qr.url.path contains "/#"
file.explode(attachments[])[].scan.qr.url.path contains "/$"
file.explode(attachments[])[].scan.qr.url.path contains "/*"
file.explode(attachments[])[].scan.qr.url.domain.subdomain regex_match "^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)"
file.explode(attachments[])[].scan.qr.url.path regex_match "\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/"
file.explode(attachments[])[].scan.qr.type eq "url"
strings.count func_call "strings.count(file.explode(attachments[])[].scan.qr.url.path, \"/\") == 2"
macro "attachments[].file_extension in file_extensions_macros"
and
any(beta.scan_qr(attachments).items)
and
or
and
or
beta.scan_qr(attachments[]).items[].url.path contains "!"
beta.scan_qr(attachments[]).items[].url.path contains "@"
or
beta.scan_qr(attachments[]).items[].url.path contains "%23"
beta.scan_qr(attachments[]).items[].url.path contains "%24"
beta.scan_qr(attachments[]).items[].url.path contains "%2A"
beta.scan_qr(attachments[]).items[].url.path contains "/#"
beta.scan_qr(attachments[]).items[].url.path contains "/$"
beta.scan_qr(attachments[]).items[].url.path contains "/*"
beta.scan_qr(attachments[]).items[].url.url regex_match "[!@].*(?:[$*]|%2[A43])"
and
or
beta.scan_qr(attachments[]).items[].url.path contains "/#"
beta.scan_qr(attachments[]).items[].url.path contains "/$"
beta.scan_qr(attachments[]).items[].url.path contains "/*"
beta.scan_qr(attachments[]).items[].url.domain.subdomain regex_match "^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)"
beta.scan_qr(attachments[]).items[].url.path regex_match "\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/"
beta.scan_qr(attachments[]).items[].type is_not_null
strings.count func_call "strings.count(beta.scan_qr(attachments[]).items[].url.path, \"/\") == 2"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_types_images"
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.
Attachment: QR code with suspicious URL patterns in EML file
#Detects EML attachments containing QR codes that link to URLs with suspicious patterns, including specific alphanumeric combinations in subdomains and paths, or special characters followed by encoded terminators. These patterns are commonly used to evade detection in credential theft attacks.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(attachments,
// Email Attachments
any(file.parse_eml(.).attachments,
(
// looks for office docs in the attached eml
.file_extension in $file_extensions_macros
and any(file.explode(.),
.scan.qr.type == "url"
// QR code URL contains recipient's email (targeting indicator)
and any(recipients.to,
.email.domain.valid
and (
// Plaintext email address in URL
strings.icontains(..scan.qr.url.url,
.email.email
)
// OR base64 encoded email address
or any(strings.scan_base64(..scan.qr.url.url,
format="url",
ignore_padding=true
),
strings.icontains(., ..email.email)
)
)
)
// a single path
and strings.count(.scan.qr.url.path, '/') == 2
and (
(
(
strings.contains(.scan.qr.url.path, '/$')
or strings.contains(.scan.qr.url.path, '/*')
or strings.contains(.scan.qr.url.path, '/#')
)
// subdomain should contain num{3}alpha or alphanum{3}
and regex.icontains(.scan.qr.url.domain.subdomain,
'^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)'
)
// url path should contain num{3}alpha or alphanum{3}
and regex.icontains(.scan.qr.url.path,
'\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/'
)
)
or (
// special char in the path
(
strings.contains(.scan.qr.url.path, '!')
or strings.contains(.scan.qr.url.path, '@')
)
and (
strings.contains(.scan.qr.url.path, '/$')
or strings.contains(.scan.qr.url.path, '/*')
or strings.contains(.scan.qr.url.path, '/#')
// hex dollar sign
or strings.icontains(.scan.qr.url.path, '%24')
// hex star
or strings.icontains(.scan.qr.url.path, '%2A')
// hex pound
or strings.icontains(.scan.qr.url.path, '%23')
)
// ensure expected ordering
and regex.icontains(.scan.qr.url.url,
'[!@].*(?:[$*]|%2[A43])'
)
)
)
)
)
or (
// looks for pdfs and images in the attached eml
//
// 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(beta.scan_qr(.).items,
.type is not null
// a single path
and strings.count(.url.path, '/') == 2
and (
(
(
strings.contains(.url.path, '/$')
or strings.contains(.url.path, '/*')
or strings.contains(.url.path, '/#')
)
// subdomain should contain num{3}alpha or alphanum{3}
and regex.icontains(.url.domain.subdomain,
'^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)'
)
// url path should contain num{3}alpha or alphanum{3}
and regex.icontains(.url.path,
'\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/'
)
)
or (
// special char in the path
(
strings.contains(.url.path, '!')
or strings.contains(.url.path, '@')
)
and (
strings.contains(.url.path, '/$')
or strings.contains(.url.path, '/*')
or strings.contains(.url.path, '/#')
// hex dollar sign
or strings.icontains(.url.path, '%24')
// hex star
or strings.icontains(.url.path, '%2A')
// hex pound
or strings.icontains(.url.path, '%23')
)
// ensure expected ordering
and regex.icontains(.url.url, '[!@].*(?:[$*]|%2[A43])')
)
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects EML attachments containing QR codes that link to URLs with suspicious patterns, including specific alphanumeric combinations in subdomains and paths, or special characters followed by encoded terminators. These patterns are commonly used to evade detection in credential theft attacks.
- inbound message
- length(recipients.to) is 1
- recipients.to[0].email.domain.valid
any of
attachmentswhere:any of
file.parse_eml(.).attachmentswhere any holds:all of:
- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
any of
recipients.towhere all hold:- .email.domain.valid
any of:
- strings.icontains(.scan.qr.url.url)
any of
strings.scan_base64(.scan.qr.url.url)where:- strings.icontains(.)
- strings.count(.scan.qr.url.path, '/') is 2
any of:
all of:
any of:
- .scan.qr.url.path contains '/$'
- .scan.qr.url.path contains '/*'
- .scan.qr.url.path contains '/#'
- .scan.qr.url.domain.subdomain matches '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)'
- .scan.qr.url.path matches '\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/'
all of:
any of:
- .scan.qr.url.path contains '!'
- .scan.qr.url.path contains '@'
.scan.qr.url.path contains any of 6 patterns
/$/*/#%24%2A%23
- .scan.qr.url.url matches '[!@].*(?:[$*]|%2[A43])'
any of
beta.scan_qr(.).itemswhere all hold:- .type is set
- strings.count(.url.path, '/') is 2
any of:
all of:
any of:
- .url.path contains '/$'
- .url.path contains '/*'
- .url.path contains '/#'
- .url.domain.subdomain matches '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)'
- .url.path matches '\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/'
all of:
any of:
- .url.path contains '!'
- .url.path contains '@'
.url.path contains any of 6 patterns
/$/*/#%24%2A%23
- .url.url matches '[!@].*(?:[$*]|%2[A43])'
Inspects: recipients.to, recipients.to[0].email.domain.valid, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: beta.scan_qr, file.explode, file.parse_eml, regex.icontains, strings.contains, strings.count, strings.icontains, strings.scan_base64. Reference lists: $file_extensions_macros.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.type | equals | url |
strings.contains | substring | /$ |
strings.contains | substring | /* |
strings.contains | substring | /# |
regex.icontains | regex | ^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.) |
regex.icontains | regex | \/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/ |
strings.contains | substring | ! |
strings.contains | substring | @ |
strings.icontains | substring | %24 |
strings.icontains | substring | %2A |
strings.icontains | substring | %23 |
regex.icontains | regex | [!@].*(?:[$*]|%2[A43]) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.parse_eml(attachments).attachments)
or
and
any(file.explode(file.parse_eml(attachments).attachments))
and
any(recipients.to)
and
or
any(strings.scan_base64(file.explode(file.parse_eml(attachments).attachments).scan.qr.url.url))
strings.icontains func_call "strings.icontains(strings.scan_base64(file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.url)[])"
strings.icontains func_call "strings.icontains(file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.url)"
recipients.to.email.domain.valid eq "true"
or
and
or
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "!"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "@"
or
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "%23"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "%24"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "%2A"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/#"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/$"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/*"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.url regex_match "[!@].*(?:[$*]|%2[A43])"
and
or
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/#"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/$"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path contains "/*"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.domain.subdomain regex_match "^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path regex_match "\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/"
file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.type eq "url"
strings.count func_call "strings.count(file.explode(file.parse_eml(attachments[]).attachments[])[].scan.qr.url.path, \"/\") == 2"
macro "file.parse_eml(attachments[]).attachments[].file_extension in file_extensions_macros"
any(beta.scan_qr(file.parse_eml(attachments).attachments).items)
and
or
and
or
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "!"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "@"
or
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "%23"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "%24"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "%2A"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/#"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/$"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/*"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.url regex_match "[!@].*(?:[$*]|%2[A43])"
and
or
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/#"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/$"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path contains "/*"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.domain.subdomain regex_match "^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].url.path regex_match "\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/"
beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].type is_not_null
strings.count func_call "strings.count(beta.scan_qr(file.parse_eml(attachments[]).attachments[]).items[].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.
Attachment: QR code with userinfo portion
#Detects inbound messages that contain image or document attachments with QR codes containing embedded usernames, passwords, or excessively padded URLs. This technique is used to bypass traditional text-based detection methods.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, Image as content, PDF, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_type in $file_types_images
or .file_extension in $file_extensions_macros
or .file_type == "pdf"
)
and any(file.explode(.),
(
.scan.qr.url.username is not null
or .scan.qr.url.password is not null
// keep in sync with https://github.com/sublime-security/sublime-rules/blob/main/detection-rules/link_userinfo_excessive_padding.yml
or regex.icontains(coalesce(.scan.qr.url.rewrite.original,
.scan.qr.url.url
),
'https?(?:(?:%3a|\:)?(?:\/|%2f){2})[^\/]+(?:\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\/]+(?:\/|%(?:25)?2f)'
)
)
and .scan.qr.url.domain.root_domain != sender.email.domain.root_domain
and not any(recipients.to,
.email.domain.root_domain == ..scan.qr.url.domain.root_domain
)
and not any(recipients.cc,
.email.domain.root_domain == ..scan.qr.url.domain.root_domain
)
// an error to strings.parse_email returns null for the full object
// this cehck ensures that the url is not a valid email address
and strings.parse_email(.scan.qr.url.url).email is null
)
)
Detection logic
Scope: inbound message.
Detects inbound messages that contain image or document attachments with QR codes containing embedded usernames, passwords, or excessively padded URLs. This technique is used to bypass traditional text-based detection methods.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_extension in $file_extensions_macros
- .file_type is 'pdf'
any of
file.explode(.)where all hold:any of:
- .scan.qr.url.username is set
- .scan.qr.url.password is set
- coalesce(.scan.qr.url.rewrite.original, .scan.qr.url.url) matches 'https?(?:(?:%3a|\\:)?(?:\\/|%2f){2})[^\\/]+(?:\\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\\/]+(?:\\/|%(?:25)?2f)'
- .scan.qr.url.domain.root_domain is not sender.email.domain.root_domain
not:
any of
recipients.towhere:- .email.domain.root_domain is .scan.qr.url.domain.root_domain
not:
any of
recipients.ccwhere:- .email.domain.root_domain is .scan.qr.url.domain.root_domain
- strings.parse_email(.scan.qr.url.url).email is missing
Inspects: attachments[].file_extension, attachments[].file_type, recipients.cc, recipients.cc[].email.domain.root_domain, recipients.to, recipients.to[].email.domain.root_domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, regex.icontains, strings.parse_email. Reference lists: $file_extensions_macros, $file_types_images.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | https?(?:(?:%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(attachments)
and
any(file.explode(attachments))
and
not
any(recipients.cc)
recipients.cc.email.domain.root_domain cross_field_compare "file.explode(attachments[])[].scan.qr.url.domain.root_domain"
not
any(recipients.to)
recipients.to.email.domain.root_domain cross_field_compare "file.explode(attachments[])[].scan.qr.url.domain.root_domain"
or
coalesce(file.explode(attachments[])[].scan.qr.url.rewrite.original, file.explode(attachments[])[].scan.qr.url.url) regex_match "https?(?:(?:%3a|\\:)?(?:\\/|%2f){2})[^\\/]+(?:\\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\\/]+(?:\\/|%(?:25)?2f)"
file.explode(attachments[])[].scan.qr.url.password is_not_null
file.explode(attachments[])[].scan.qr.url.username is_not_null
file.explode(attachments[])[].scan.qr.url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
strings.parse_email(file.explode(attachments[])[].scan.qr.url.url).email is_null
or
attachments.file_type eq "pdf"
macro "attachments[].file_extension in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RDP connection file
#Recursively scans files and archives to detect RDP connection files. Coercing a target user into connecting to an attacker-owned RDP server can expose elements of their host and potentially lead to compromise.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments, .file_extension =~ "rdp")
or (
any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.), .file_extension =~ "rdp")
)
)
)
Detection logic
Scope: inbound message.
Recursively scans files and archives to detect RDP connection files. Coercing a target user into connecting to an attacker-owned RDP server can expose elements of their host and potentially lead to compromise.
- inbound message
any of:
any of
attachmentswhere:- .file_extension is 'rdp'
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .file_extension is 'rdp'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $file_extensions_common_archives.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | rdp |
file.explode(attachments[])[].file_extension | equals | rdp |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
and
any(file.explode(attachments))
file.explode(attachments).file_extension eq "rdp"
macro "attachments[].file_extension in file_extensions_common_archives"
any(attachments)
attachments.file_extension eq "rdp"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RFC822 containing suspicious file sharing language with links from untrusted sender
#This rule identifies messages with an RFC822 attachment contains language indicative of suspicious file-sharing activity. It checks both the original sender and the nested sender against highly trusted domains. The original message is unsolicited, and has not been previously flagged as a false positive.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "unknown"
and (.content_type == "message/rfc822" or .file_extension in ('eml'))
and regex.contains(file.parse_eml(.).subject.subject,
'(shared.{0,30}with you|View Document)'
)
and 0 < length(file.parse_eml(.).body.links) < 10
and file.parse_eml(.).sender.email.email not in $recipient_emails
// exclude bounce backs & read receipts
and not strings.like(file.parse_eml(.).sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
and not regex.imatch(file.parse_eml(.).subject.subject,
"(undeliverable|read:).*"
)
and not any(file.parse_eml(.).attachments,
.content_type == "message/delivery-status"
)
// negate highly trusted sender domains in the nested eml unless they fail DMARC
and (
(
file.parse_eml(.).sender.email.domain.root_domain in $high_trust_sender_root_domains
and (
any(distinct(file.parse_eml(.).headers.hops,
.authentication_results.dmarc is not null
),
strings.ilike(.authentication_results.dmarc, "*fail")
)
)
)
or file.parse_eml(.).sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
// negate org domains that passed dmarc
and not file.parse_eml(.).sender.email.domain.root_domain in $org_domains
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and (
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
)
)
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
This rule identifies messages with an RFC822 attachment contains language indicative of suspicious file-sharing activity. It checks both the original sender and the nested sender against highly trusted domains. The original message is unsolicited, and has not been previously flagged as a false positive.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'unknown'
any of:
- .content_type is 'message/rfc822'
- .file_extension in ('eml')
- file.parse_eml(.).subject.subject matches '(shared.{0,30}with you|View Document)'
all of:
- length(file.parse_eml(.).body.links) > 0
- length(file.parse_eml(.).body.links) < 10
- file.parse_eml(.).sender.email.email not in $recipient_emails
not:
file.parse_eml(.).sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
- file.parse_eml(.).subject.subject matches '(undeliverable|read:).*'
not:
any of
file.parse_eml(.).attachmentswhere:- .content_type is 'message/delivery-status'
any of:
all of:
- file.parse_eml(.).sender.email.domain.root_domain in $high_trust_sender_root_domains
any of
distinct(...)where:- .authentication_results.dmarc matches '*fail'
- file.parse_eml(.).sender.email.domain.root_domain not in $high_trust_sender_root_domains
not:
- file.parse_eml(.).sender.email.domain.root_domain in $org_domains
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
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.hops, headers.hops[].authentication_results.dmarc, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_eml, profile.by_sender, regex.contains, regex.imatch, strings.ilike, strings.like. Reference lists: $high_trust_sender_root_domains, $org_domains, $recipient_emails.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
regex.contains | regex | (shared.{0,30}with you|View Document) |
strings.ilike | substring | *fail |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
any(distinct(...))
distinct(...).authentication_results.dmarc ends_with "fail"
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.domain.root_domain in high_trust_sender_root_domains"
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.domain.root_domain not in high_trust_sender_root_domains"
not
any(file.parse_eml(attachments).attachments)
file.parse_eml(attachments).attachments.content_type eq "message/delivery-status"
not
or
file.parse_eml(attachments[]).sender.email.local_part match "administrator"
file.parse_eml(attachments[]).sender.email.local_part match "mailer-daemon"
file.parse_eml(attachments[]).sender.email.local_part match "postmaster"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
not
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.domain.root_domain in org_domains"
not
file.parse_eml(attachments[]).subject.subject regex_match "(undeliverable|read:).*"
attachments.file_type eq "unknown"
file.parse_eml func_call "file.parse_eml(attachments[]).sender.email.email not in recipient_emails"
file.parse_eml(attachments[]).body.links length_compare "0"
file.parse_eml(attachments[]).body.links length_compare "10"
file.parse_eml(attachments[]).subject.subject regex_match "(shared.{0,30}with you|View Document)"
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"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RFP/RFQ impersonating government entities
#Attached RFP/RFQ impersonates a U.S. government department or entity to commit fraudulent transactions.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Impersonation: Brand, PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and all(attachments,
.file_extension in~ $file_extensions_macros or .file_type == "pdf"
)
and regex.icontains(body.current_thread.text, "department of|office of")
and (
regex.icontains(subject.subject,
'(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)'
)
or any(attachments,
regex.icontains(.file_name,
'(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)'
)
)
)
and strings.icontains(sender.email.domain.domain, "gov")
and (
any(ml.nlu_classifier(body.current_thread.text).tags,
.name == "purchase_order"
)
and any(attachments,
any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).entities,
regex.icontains(.text, "department of|office of")
)
)
)
)
Detection logic
Scope: inbound message.
Attached RFP/RFQ impersonates a U.S. government department or entity to commit fraudulent transactions.
- inbound message
- length(attachments) is 1
all of
attachmentswhere any holds:- .file_extension in $file_extensions_macros
- .file_type is 'pdf'
- body.current_thread.text matches 'department of|office of'
any of:
- subject.subject matches '(request for (purchase|quot(e|ation))|\\bRFQ\\b|\\bRFP\\b)'
any of
attachmentswhere:- .file_name matches '(request for (purchase|quot(e|ation))|\\bRFQ\\b|\\bRFP\\b)'
- sender.email.domain.domain contains 'gov'
all of:
any of
ml.nlu_classifier(body.current_thread.text).tagswhere:- .name is 'purchase_order'
any of
attachmentswhere:any of
file.explode(.)where:any of
ml.nlu_classifier(.scan.ocr.raw).entitieswhere:- .text matches 'department of|office of'
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, sender.email.domain.domain, subject.subject, type.inbound. Sensors: file.explode, ml.nlu_classifier, regex.icontains, strings.icontains. Reference lists: $file_extensions_macros.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
regex.icontains | regex | department of|office of |
regex.icontains | regex | (request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b) |
strings.icontains | substring | gov |
ml.nlu_classifier(body.current_thread.text).tags[].name | equals | purchase_order |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
any(file.explode(attachments))
any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities.text regex_match "department of|office of"
or
any(attachments)
attachments.file_name regex_match "(request for (purchase|quot(e|ation))|\\bRFQ\\b|\\bRFP\\b)"
subject.subject regex_match "(request for (purchase|quot(e|ation))|\\bRFQ\\b|\\bRFP\\b)"
any(ml.nlu_classifier(body.current_thread.text).tags)
ml.nlu_classifier(body.current_thread.text).tags.name eq "purchase_order"
attachments length_compare "1"
body.current_thread.text regex_match "department of|office of"
sender.email.domain.domain contains "gov"
type.inbound eq "true"
macro "all(attachments)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match |
sender.email.domain.domain | contains |
| field:"sender.email.domain.domain" kind:contains value:"gov" |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match value:"(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Romance scam with image lure and advance-fee or suspicious link indicators
#Detects inbound messages that are not replies, forwards, or mailing list communications, and contain image attachments (JPG or PNG) alongside body text classified as romantic or sexually explicit in nature. The messages either include links to known redirector or free hosting domains (such as geno.link or sites.google.com), or exhibit advance-fee fraud intent while routing replies to a free email provider despite originating from a corporate-looking sender domain. Senders observed span spoofed government and business addresses as well as free webmail accounts, with subject lines using romantic or personal connection lures.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Spam |
| Tactics and techniques | Social engineering, Image as content, Free email provider, Free file host, Out of band pivot |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and not subject.is_reply
and not subject.is_forward
and not any(headers.hops,
any(.fields,
strings.ilike(.name, "List-Id")
or strings.ilike(.name, "List-Unsubscribe")
)
)
and any(attachments, .file_type in ("jpg", "png"))
and any(ml.nlu_classifier(body.current_thread.text).topics,
.name in ("Romance", "Sexually Explicit Messages")
and .confidence != 'low'
)
and (
any(body.links, .href_url.domain.domain in ("geno.link", "sites.google.com"))
or (
any(headers.reply_to, .email.domain.root_domain in $free_email_providers)
and sender.email.domain.root_domain not in $free_email_providers
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "advance_fee" and .confidence != 'low'
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages that are not replies, forwards, or mailing list communications, and contain image attachments (JPG or PNG) alongside body text classified as romantic or sexually explicit in nature. The messages either include links to known redirector or free hosting domains (such as geno.link or sites.google.com), or exhibit advance-fee fraud intent while routing replies to a free email provider despite originating from a corporate-looking sender domain. Senders observed span spoofed government and business addresses as well as free webmail accounts, with subject lines using romantic or personal connection lures.
- inbound message
not:
- subject.is_reply
not:
- subject.is_forward
not:
any of
headers.hopswhere:any of
.fieldswhere any holds:- .name matches 'List-Id'
- .name matches 'List-Unsubscribe'
any of
attachmentswhere:- .file_type in ('jpg', 'png')
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name in ('Romance', 'Sexually Explicit Messages')
- .confidence is not 'low'
any of:
any of
body.linkswhere:- .href_url.domain.domain in ('geno.link', 'sites.google.com')
all of:
any of
headers.reply_towhere:- .email.domain.root_domain in $free_email_providers
- sender.email.domain.root_domain not in $free_email_providers
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'advance_fee'
- .confidence is not 'low'
Inspects: attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.domain.domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.reply_to, headers.reply_to[].email.domain.root_domain, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: ml.nlu_classifier, strings.ilike. Reference lists: $free_email_providers.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | jpg |
attachments[].file_type | member | png |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | Romance |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | Sexually Explicit Messages |
body.links[].href_url.domain.domain | member | geno.link |
body.links[].href_url.domain.domain | member | sites.google.com |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | advance_fee |
Stages and Predicates
Stage 1: mql_rule
and
not
any(headers.hops)
any(headers.hops.fields)
or
headers.hops.fields[].name eq "List-Id"
headers.hops.fields[].name eq "List-Unsubscribe"
or
and
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 "advance_fee"
any(headers.reply_to)
macro "headers.reply_to[].email.domain.root_domain in free_email_providers"
macro "sender.email.domain.root_domain not in free_email_providers"
any(body.links)
body.links.href_url.domain.domain in ["geno.link", "sites.google.com"]
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 ["Romance", "Sexually Explicit Messages"]
any(attachments)
attachments.file_type in ["jpg", "png"]
not
subject.is_forward eq "true"
not
subject.is_reply eq "true"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
subject.is_forward | eq | true | excludes:subject.is_forward field:"subject.is_forward" value:"true" |
subject.is_reply | eq | true | excludes:subject.is_reply field:"subject.is_reply" value:"true" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RTF file with suspicious link
#This rule detects RTF attachments directly attached or within an archive, containing an external link to a suspicious low reputation domain.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_common_archives
or .file_type == "rtf"
)
and any(file.explode(.),
.flavors.mime == 'text/rtf'
and any(.scan.url.urls,
.domain.valid
and .domain.subdomain is not null
and not (
strings.ends_with(.url, "jpeg")
or strings.ends_with(.url, "png")
)
and (
(
.domain.root_domain not in $tranco_1m
and .domain.root_domain not in $umbrella_1m
)
or (
.domain.root_domain in $free_file_hosts
or .domain.root_domain in $free_file_hosts
or .domain.root_domain in $free_subdomain_hosts
or .domain.root_domain in $url_shorteners
or .domain.root_domain in $social_landing_hosts
)
// or the url contains the recipient email and the root_domain is not in tranco
or (
any(recipients.to,
strings.icontains(..url, .email.email)
)
and (
.domain.root_domain not in $tranco_1m
and .domain.root_domain not in $umbrella_1m
)
)
)
)
)
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
This rule detects RTF attachments directly attached or within an archive, containing an external link to a suspicious low reputation domain.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_type is 'rtf'
any of
file.explode(.)where all hold:- .flavors.mime is 'text/rtf'
any of
.scan.url.urlswhere all hold:- .domain.valid
- .domain.subdomain is set
none of:
- .url ends with 'jpeg'
- .url ends with 'png'
any of:
all of:
- .domain.root_domain not in $tranco_1m
- .domain.root_domain not in $umbrella_1m
any of:
- .domain.root_domain in $free_file_hosts
- .domain.root_domain in $free_file_hosts
- .domain.root_domain in $free_subdomain_hosts
- .domain.root_domain in $url_shorteners
- .domain.root_domain in $social_landing_hosts
all of:
any of
recipients.towhere:- strings.icontains(.url)
all of:
- .domain.root_domain not in $tranco_1m
- .domain.root_domain not in $umbrella_1m
not:
- profile.by_sender().solicited
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].file_extension, attachments[].file_type, recipients.to, recipients.to[].email.email, type.inbound. Sensors: file.explode, profile.by_sender, strings.ends_with, strings.icontains. Reference lists: $file_extensions_common_archives, $free_file_hosts, $free_subdomain_hosts, $social_landing_hosts, $tranco_1m, $umbrella_1m, $url_shorteners.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rtf |
file.explode(attachments[])[].flavors.mime | equals | text/rtf |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
and
or
and
any(recipients.to)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.url.urls[].url)"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in tranco_1m"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in umbrella_1m"
and
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in tranco_1m"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain not in umbrella_1m"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_file_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in social_landing_hosts"
macro "file.explode(attachments[])[].scan.url.urls[].domain.root_domain in url_shorteners"
not
or
file.explode(attachments[])[].scan.url.urls[].url ends_with "jpeg"
file.explode(attachments[])[].scan.url.urls[].url ends_with "png"
file.explode(attachments[])[].scan.url.urls[].domain.subdomain is_not_null
file.explode(attachments[])[].scan.url.urls[].domain.valid eq "true"
file.explode(attachments[])[].flavors.mime eq "text/rtf"
or
attachments.file_type eq "rtf"
macro "attachments[].file_extension in file_extensions_common_archives"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
not
profile.by_sender func_call "profile.by_sender().solicited"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RTF with embedded content
#RTF files can contain embedded content similar to OLE files (Microsoft Office documents.)
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "rtf"
and any(file.explode(.),
.flavors.mime in~ (
"application/x-dosexec",
"text/x-msdos-batch",
"application/octet-stream"
)
or any(.flavors.yara, . == 'base64_pe')
or .file_extension in~ ("bat", "exe", "vbs")
)
)
Detection logic
Scope: inbound message.
RTF files can contain embedded content similar to OLE files (Microsoft Office documents.)
- inbound message
any of
attachmentswhere all hold:- .file_type is 'rtf'
any of
file.explode(.)where any holds:- .flavors.mime in ('application/x-dosexec', 'text/x-msdos-batch', 'application/octet-stream')
any of
.flavors.yarawhere:- . is 'base64_pe'
- .file_extension in ('bat', 'exe', 'vbs')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rtf |
file.explode(attachments[])[].flavors.mime | member | application/x-dosexec |
file.explode(attachments[])[].flavors.mime | member | text/x-msdos-batch |
file.explode(attachments[])[].flavors.mime | member | application/octet-stream |
file.explode(attachments[])[].flavors.yara[] | equals | base64_pe |
file.explode(attachments[])[].file_extension | member | bat |
file.explode(attachments[])[].file_extension | member | exe |
file.explode(attachments[])[].file_extension | member | vbs |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).flavors.yara)
file.explode(attachments).flavors.yara eq "base64_pe"
file.explode(attachments[])[].file_extension in ["bat", "exe", "vbs"]
file.explode(attachments[])[].flavors.mime in ["application/octet-stream", "application/x-dosexec", "text/x-msdos-batch"]
attachments.file_type eq "rtf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: RTF with link to free-hosted Cloudflare Pages
#Detects inbound emails that contain an RTF attachment. The rule extracts embedded content from the RTF file and inspects any URLs found within it, following redirects and analyzing the final destination page's links. It flags cases where those links point to domains hosted on the free Cloudflare Pages service (pages.dev), a common tactic used to host malicious or deceptive content while evading detection.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free subdomain host |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == 'rtf'),
any(file.explode(.),
any(.scan.url.urls,
any(ml.link_analysis(.).final_dom.links,
.href_url.domain.root_domain in ('pages.dev')
)
)
)
)
Detection logic
Scope: inbound message.
Detects inbound emails that contain an RTF attachment. The rule extracts embedded content from the RTF file and inspects any URLs found within it, following redirects and analyzing the final destination page's links. It flags cases where those links point to domains hosted on the free Cloudflare Pages service (pages.dev), a common tactic used to host malicious or deceptive content while evading detection.
- inbound message
any of
filter(attachments)where:any of
file.explode(.)where:any of
.scan.url.urlswhere:any of
ml.link_analysis(.).final_dom.linkswhere:- .href_url.domain.root_domain in ('pages.dev')
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, ml.link_analysis.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | rtf |
ml.link_analysis(file.explode(filter(attachments)[])[].scan.url.urls[]).final_dom.links[].href_url.domain.root_domain | member | pages.dev |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.url.urls)
any(ml.link_analysis(file.explode(filter(attachments)).scan.url.urls).final_dom.links)
ml.link_analysis(file.explode(filter(attachments)).scan.url.urls).final_dom.links.href_url.domain.root_domain eq "pages.dev"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Self-sender PDF with minimal content and view prompt
#Detects messages where the sender and recipient are the same address with a PDF attachment containing only 'VIEW PDF' text and a standardized body message requesting to view the attachment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// self sender
and length(recipients.to) == 1
and (
sender.email.email == recipients.to[0].email.email
or recipients.to[0].email.domain.valid == false
)
and strings.starts_with(body.current_thread.text, 'Please see attached')
and any(filter(attachments, .file_type == 'pdf'),
any(file.explode(.),
.scan.strings.strings[0] == 'VIEW PDF'
and length(.scan.strings.strings) == 1
)
)
Detection logic
Scope: inbound message.
Detects messages where the sender and recipient are the same address with a PDF attachment containing only 'VIEW PDF' text and a standardized body message requesting to view the attachment.
- inbound message
- length(recipients.to) is 1
any of:
- sender.email.email is recipients.to[0].email.email
- recipients.to[0].email.domain.valid is False
- body.current_thread.text starts with 'Please see attached'
any of
filter(attachments)where:any of
file.explode(.)where all hold:- .scan.strings.strings[0] is 'VIEW PDF'
- length(.scan.strings.strings) is 1
Inspects: attachments[].file_type, body.current_thread.text, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: file.explode, strings.starts_with.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.starts_with | prefix | Please see attached |
attachments[].file_type | equals | pdf |
file.explode(filter(attachments)[])[].scan.strings.strings[0] | equals | VIEW PDF |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(file.explode(filter(attachments)))
and
file.explode(filter(attachments)[])[].scan.strings.strings length_compare "1"
file.explode(filter(attachments)[])[].scan.strings.strings[0] eq "VIEW PDF"
or
recipients.to[0].email.domain.valid eq "false"
sender.email.email cross_field_compare "recipients.to[0].email.email"
body.current_thread.text starts_with "Please see attached"
recipients.to length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | starts_with |
| field:"body.current_thread.text" kind:starts_with value:"Please see attached" |
recipients.to[0].email.domain.valid | eq |
| field:"recipients.to[0].email.domain.valid" kind:eq value:"false" |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: SFX archive containing commands
#Attachment is an SFX archive that contains commands that will execute when opened. This can be used to run malicious commands, and has been observed in the wild.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ ("exe", "sfx")
and any(file.explode(.),
any(.scan.strings.strings,
strings.ilike(.,
'CMT;The comment below contains SFX script commands'
)
)
and any(.scan.strings.strings, strings.ilike(., 'Setup=*'))
)
)
Detection logic
Scope: inbound message.
Attachment is an SFX archive that contains commands that will execute when opened. This can be used to run malicious commands, and has been observed in the wild.
- inbound message
any of
attachmentswhere all hold:- .file_extension in ('exe', 'sfx')
any of
file.explode(.)where all hold:any of
.scan.strings.stringswhere:- . matches 'CMT;The comment below contains SFX script commands'
any of
.scan.strings.stringswhere:- . matches 'Setup=*'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.ilike.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | exe |
attachments[].file_extension | member | sfx |
strings.ilike | substring | CMT;The comment below contains SFX script commands |
strings.ilike | substring | Setup=* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings eq "CMT;The comment below contains SFX script commands"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings starts_with "Setup="
attachments.file_extension in ["exe", "sfx"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Single-page PDF with S3-hosted HTML link
#Detects inbound messages containing a single-page PDF attachment that includes exactly one URL, which links directly to an HTML file hosted on an Amazon S3 bucket. This technique is commonly used to redirect recipients to credential harvesting pages while leveraging trusted cloud infrastructure to evade detection.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Free file host, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
// a single page pdf
and beta.parse_exif(.).page_count == 1
and any(file.explode(.),
length(.scan.pdf.urls) == 1
and any(.scan.pdf.urls,
strings.contains(.path, '.html')
and // links directly to a S3 bucket
.domain.root_domain == "amazonaws.com"
and strings.icontains(.domain.subdomain, "s3")
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing a single-page PDF attachment that includes exactly one URL, which links directly to an HTML file hosted on an Amazon S3 bucket. This technique is commonly used to redirect recipients to credential harvesting pages while leveraging trusted cloud infrastructure to evade detection.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
- beta.parse_exif(.).page_count is 1
any of
file.explode(.)where all hold:- length(.scan.pdf.urls) is 1
any of
.scan.pdf.urlswhere all hold:- .path contains '.html'
- .domain.root_domain is 'amazonaws.com'
- .domain.subdomain contains 's3'
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode, strings.contains, strings.icontains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.contains | substring | .html |
file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain | equals | amazonaws.com |
strings.icontains | substring | s3 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.pdf.urls)
and
file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain eq "amazonaws.com"
file.explode(attachments[])[].scan.pdf.urls[].domain.subdomain contains "s3"
file.explode(attachments[])[].scan.pdf.urls[].path contains ".html"
file.explode(attachments[])[].scan.pdf.urls length_compare "1"
attachments.file_type eq "pdf"
beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Small text file with link containing recipient email address
#Attach text file is less than 1000 bytes and contains a recipients email address. Seen in the wild carrying credential phishing links.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.content_type in~ ("text/plain", "text")
// negate calendar invites
and not (
.file_extension == "ics"
or .content_type in ("application/ics", "text/calendar")
)
and any(file.explode(.),
.size < 1000
and any(.scan.url.urls,
any(recipients.to,
strings.icontains(..url, .email.email)
and .email.domain.valid
)
)
)
)
Detection logic
Scope: inbound message.
Attach text file is less than 1000 bytes and contains a recipients email address. Seen in the wild carrying credential phishing links.
- inbound message
any of
attachmentswhere all hold:- .content_type in ('text/plain', 'text')
none of:
- .file_extension is 'ics'
- .content_type in ('application/ics', 'text/calendar')
any of
file.explode(.)where all hold:- .size < 1000
any of
.scan.url.urlswhere:any of
recipients.towhere all hold:- strings.icontains(.url)
- .email.domain.valid
Inspects: attachments[].content_type, attachments[].file_extension, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | member | text/plain |
attachments[].content_type | member | text |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.url.urls)
any(recipients.to)
and
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.url.urls[].url)"
file.explode(attachments[])[].size lt "1000"
not
or
attachments.content_type in ["application/ics", "text/calendar"]
attachments.file_extension eq "ics"
attachments.content_type in ["text", "text/plain"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Soda PDF producer with encryption themes
#Detects an observed TTP of using Soda PDF (which offers a free trial) to produce PDFs which OCR output contains references to encryption and mentions a PDF. The PDF contains a single link which has been observed linking to a credential phishing page.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension == "pdf"
// observed producer
and any(file.explode(.), .scan.exiftool.producer == "Soda PDF")
and any(file.explode(.),
// OCR contains "encryption" themes
(
strings.icontains(.scan.ocr.raw, "has been encrypted")
or strings.icontains(.scan.ocr.raw, "encrypted pdf file")
or strings.icontains(.scan.ocr.raw, "is secured by")
)
// mentions a PDF
and strings.contains(.scan.ocr.raw, "PDF")
)
)
Detection logic
Scope: inbound message.
Detects an observed TTP of using Soda PDF (which offers a free trial) to produce PDFs which OCR output contains references to encryption and mentions a PDF. The PDF contains a single link which has been observed linking to a credential phishing page.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'pdf'
any of
file.explode(.)where:- .scan.exiftool.producer is 'Soda PDF'
any of
file.explode(.)where all hold:any of:
- .scan.ocr.raw contains 'has been encrypted'
- .scan.ocr.raw contains 'encrypted pdf file'
- .scan.ocr.raw contains 'is secured by'
- .scan.ocr.raw contains 'PDF'
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode, strings.contains, strings.icontains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
file.explode(attachments[])[].scan.exiftool.producer | equals | Soda PDF |
strings.icontains | substring | has been encrypted |
strings.icontains | substring | encrypted pdf file |
strings.icontains | substring | is secured by |
strings.contains | substring | PDF |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
file.explode(attachments[])[].scan.ocr.raw contains "encrypted pdf file"
file.explode(attachments[])[].scan.ocr.raw contains "has been encrypted"
file.explode(attachments[])[].scan.ocr.raw contains "is secured by"
file.explode(attachments[])[].scan.ocr.raw contains "PDF"
any(file.explode(attachments))
file.explode(attachments).scan.exiftool.producer eq "Soda PDF"
attachments.file_extension eq "pdf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Suspicious employee policy update document lure
#Inbound message containing subject line and attachments related to handbook, compensation, or policy updates. Attachments are limited to Microsoft Word documents and match similar update-related terminology. This pattern has been observed used to delivery credential phishing via QR codes.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | PDF, Social engineering, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// NOTE: This rule is designed for these values to match/sync subject.base and file names
and (
// the subject contains pay related items
(
strings.icontains(subject.base, 'salary')
or regex.icontains(subject.base, '\bpay(?:out|roll|\b)')
or strings.icontains(subject.base, 'remuneration')
or strings.icontains(subject.base, 'bonus')
or strings.icontains(subject.base, 'incentive')
or strings.icontains(subject.base, 'merit\b')
or strings.icontains(subject.base, 'handbook')
or strings.icontains(subject.base, 'benefits')
or strings.icontains(subject.base, 'earnings')
or strings.icontains(subject.base, 'contract')
or regex.icontains(subject.base, 'empl[o0]yment')
)
and (
strings.icontains(subject.base, 'review')
or strings.icontains(subject.base, 'breakdown')
or strings.icontains(subject.base, 'Access Your')
or strings.icontains(subject.base, 'evaluation')
or regex.icontains(subject.base, 'eval\b')
or strings.icontains(subject.base, 'assessment')
or strings.icontains(subject.base, 'appraisal')
or strings.icontains(subject.base, 'feedback')
or strings.icontains(subject.base, 'performance')
or strings.icontains(subject.base, 'adjustment')
or strings.icontains(subject.base, 'qualification')
or strings.icontains(subject.base, 'increase')
or strings.icontains(subject.base, 'raise')
or strings.icontains(subject.base, 'change')
or strings.icontains(subject.base, 'modification')
or strings.icontains(subject.base, 'distribution')
or strings.icontains(subject.base, 'details')
or regex.icontains(subject.base, 'revis(?:ed|ion)')
or regex.icontains(subject.base, 'amend(?:ed|ment)')
or regex.icontains(subject.base, 'update(?:d| to)')
or strings.icontains(subject.base, 'plan')
or strings.icontains(subject.base, 'notification')
)
)
and 0 < length(attachments) <= 3
and any(attachments,
.file_extension in ("doc", "docx", "docm", "pdf", "pptx")
and (
strings.icontains(.file_name, 'salary')
or strings.icontains(.file_name, 'compensation')
or regex.icontains(.file_name, '\bpay(?:roll|\b)')
or strings.icontains(.file_name, 'bonus')
or strings.icontains(.file_name, 'incentive')
or strings.icontains(.file_name, 'merit\b')
or strings.icontains(.file_name, 'handbook')
or strings.icontains(.file_name, 'benefits')
or regex.icontains(.file_name, 'empl[o0]yment')
)
and (
strings.icontains(.file_name, 'review')
or strings.icontains(.file_name, 'evaluation')
or regex.icontains(.file_name, 'eval\b')
or strings.icontains(.file_name, 'assessment')
or strings.icontains(.file_name, 'appraisal')
or strings.icontains(.file_name, 'feedback')
or strings.icontains(.file_name, 'performance')
or strings.icontains(.file_name, 'adjustment')
or strings.icontains(.file_name, 'increase')
or strings.icontains(.file_name, 'increment')
or strings.icontains(.file_name, 'raise')
or strings.icontains(.file_name, 'change')
or strings.icontains(.file_name, 'modification')
or strings.icontains(.file_name, 'distribution')
or strings.icontains(.file_name, 'statement')
or regex.icontains(.file_name, 'revis(?:ed|ion)')
or regex.icontains(.file_name, 'amend(?:ed|ment)')
or regex.icontains(.file_name, 'adjust(?:ed|ment)')
or regex.icontains(.file_name, 'update(?:d| to)')
or regex.icontains(.file_name,
'(January|February|March|April|May|June|July|August|September|October|November|December)\s20[2,3]{1}\d{1}'
)
or strings.icontains(.file_name, 'contract')
or (
// file name contains recipient's email
any(recipients.to,
strings.icontains(..file_name, .email.email)
and .email.domain.valid
)
)
)
)
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.
Inbound message containing subject line and attachments related to handbook, compensation, or policy updates. Attachments are limited to Microsoft Word documents and match similar update-related terminology. This pattern has been observed used to delivery credential phishing via QR codes.
- inbound message
all of:
any of:
- subject.base contains 'salary'
- subject.base matches '\\bpay(?:out|roll|\\b)'
- subject.base contains 'remuneration'
- subject.base contains 'bonus'
- subject.base contains 'incentive'
- subject.base contains 'merit\\b'
- subject.base contains 'handbook'
- subject.base contains 'benefits'
- subject.base contains 'earnings'
- subject.base contains 'contract'
- subject.base matches 'empl[o0]yment'
any of:
- subject.base contains 'review'
- subject.base contains 'breakdown'
- subject.base contains 'Access Your'
- subject.base contains 'evaluation'
- subject.base matches 'eval\\b'
- subject.base contains 'assessment'
- subject.base contains 'appraisal'
- subject.base contains 'feedback'
- subject.base contains 'performance'
- subject.base contains 'adjustment'
- subject.base contains 'qualification'
- subject.base contains 'increase'
- subject.base contains 'raise'
- subject.base contains 'change'
- subject.base contains 'modification'
- subject.base contains 'distribution'
- subject.base contains 'details'
- subject.base matches 'revis(?:ed|ion)'
- subject.base matches 'amend(?:ed|ment)'
- subject.base matches 'update(?:d| to)'
- subject.base contains 'plan'
- subject.base contains 'notification'
all of:
- length(attachments) > 0
- length(attachments) ≤ 3
any of
attachmentswhere all hold:- .file_extension in ('doc', 'docx', 'docm', 'pdf', 'pptx')
any of:
- .file_name contains 'salary'
- .file_name contains 'compensation'
- .file_name matches '\\bpay(?:roll|\\b)'
- .file_name contains 'bonus'
- .file_name contains 'incentive'
- .file_name contains 'merit\\b'
- .file_name contains 'handbook'
- .file_name contains 'benefits'
- .file_name matches 'empl[o0]yment'
any of:
- .file_name contains 'review'
- .file_name contains 'evaluation'
- .file_name matches 'eval\\b'
- .file_name contains 'assessment'
- .file_name contains 'appraisal'
- .file_name contains 'feedback'
- .file_name contains 'performance'
- .file_name contains 'adjustment'
- .file_name contains 'increase'
- .file_name contains 'increment'
- .file_name contains 'raise'
- .file_name contains 'change'
- .file_name contains 'modification'
- .file_name contains 'distribution'
- .file_name contains 'statement'
- .file_name matches 'revis(?:ed|ion)'
- .file_name matches 'amend(?:ed|ment)'
- .file_name matches 'adjust(?:ed|ment)'
- .file_name matches 'update(?:d| to)'
- .file_name matches '(January|February|March|April|May|June|July|August|September|October|November|December)\\s20[2,3]{1}\\d{1}'
- .file_name contains 'contract'
any of
recipients.towhere all hold:- strings.icontains(.file_name)
- .email.domain.valid
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- coalesce(headers.auth_summary.dmarc.pass)
Inspects: attachments[].file_extension, attachments[].file_name, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: regex.icontains, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (44)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | salary |
regex.icontains | regex | \bpay(?:out|roll|\b) |
strings.icontains | substring | remuneration |
strings.icontains | substring | bonus |
strings.icontains | substring | incentive |
strings.icontains | substring | merit\b |
strings.icontains | substring | handbook |
strings.icontains | substring | benefits |
strings.icontains | substring | earnings |
strings.icontains | substring | contract |
regex.icontains | regex | empl[o0]yment |
strings.icontains | substring | review |
32 more
strings.icontains | substring | breakdown |
strings.icontains | substring | Access Your |
strings.icontains | substring | evaluation |
regex.icontains | regex | eval\b |
strings.icontains | substring | assessment |
strings.icontains | substring | appraisal |
strings.icontains | substring | feedback |
strings.icontains | substring | performance |
strings.icontains | substring | adjustment |
strings.icontains | substring | qualification |
strings.icontains | substring | increase |
strings.icontains | substring | raise |
strings.icontains | substring | change |
strings.icontains | substring | modification |
strings.icontains | substring | distribution |
strings.icontains | substring | details |
regex.icontains | regex | revis(?:ed|ion) |
regex.icontains | regex | amend(?:ed|ment) |
regex.icontains | regex | update(?:d| to) |
strings.icontains | substring | plan |
strings.icontains | substring | notification |
attachments[].file_extension | member | doc |
attachments[].file_extension | member | docx |
attachments[].file_extension | member | docm |
attachments[].file_extension | member | pdf |
attachments[].file_extension | member | pptx |
strings.icontains | substring | compensation |
regex.icontains | regex | \bpay(?:roll|\b) |
strings.icontains | substring | increment |
strings.icontains | substring | statement |
regex.icontains | regex | adjust(?:ed|ment) |
regex.icontains | regex | (January|February|March|April|May|June|July|August|September|October|November|December)\s20[2,3]{1}\d{1} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
any(recipients.to)
and
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(attachments[].file_name)"
attachments.file_name contains "adjustment"
attachments.file_name contains "appraisal"
attachments.file_name contains "assessment"
attachments.file_name contains "change"
attachments.file_name contains "contract"
attachments.file_name contains "distribution"
attachments.file_name contains "evaluation"
attachments.file_name contains "feedback"
attachments.file_name contains "increase"
attachments.file_name contains "increment"
attachments.file_name contains "modification"
attachments.file_name contains "performance"
attachments.file_name contains "raise"
attachments.file_name contains "review"
attachments.file_name contains "statement"
attachments.file_name regex_match "(January|February|March|April|May|June|July|August|September|October|November|December)\\s20[2,3]{1}\\d{1}"
attachments.file_name regex_match "adjust(?:ed|ment)"
attachments.file_name regex_match "amend(?:ed|ment)"
attachments.file_name regex_match "eval\\b"
attachments.file_name regex_match "revis(?:ed|ion)"
attachments.file_name regex_match "update(?:d| to)"
or
attachments.file_name contains "benefits"
attachments.file_name contains "bonus"
attachments.file_name contains "compensation"
attachments.file_name contains "handbook"
attachments.file_name contains "incentive"
attachments.file_name contains "merit\\b"
attachments.file_name contains "salary"
attachments.file_name regex_match "\\bpay(?:roll|\\b)"
attachments.file_name regex_match "empl[o0]yment"
attachments.file_extension in ["doc", "docm", "docx", "pdf", "pptx"]
not
and
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
or
subject.base contains "Access Your"
subject.base contains "adjustment"
subject.base contains "appraisal"
subject.base contains "assessment"
subject.base contains "breakdown"
subject.base contains "change"
subject.base contains "details"
subject.base contains "distribution"
subject.base contains "evaluation"
subject.base contains "feedback"
subject.base contains "increase"
subject.base contains "modification"
subject.base contains "notification"
subject.base contains "performance"
subject.base contains "plan"
subject.base contains "qualification"
subject.base contains "raise"
subject.base contains "review"
subject.base regex_match "amend(?:ed|ment)"
subject.base regex_match "eval\\b"
subject.base regex_match "revis(?:ed|ion)"
subject.base regex_match "update(?:d| to)"
or
subject.base contains "benefits"
subject.base contains "bonus"
subject.base contains "contract"
subject.base contains "earnings"
subject.base contains "handbook"
subject.base contains "incentive"
subject.base contains "merit\\b"
subject.base contains "remuneration"
subject.base contains "salary"
subject.base regex_match "\\bpay(?:out|roll|\\b)"
subject.base regex_match "empl[o0]yment"
attachments length_compare "0"
attachments length_compare "3"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
subject.base | contains |
| field:"subject.base" kind:contains |
subject.base | regex_match |
| field:"subject.base" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Suspicious PDF created with headless browser
#Detects PDF documents containing a table of contents that were generated using HeadlessChrome, Chromium with Skia/PDF, or QT with empty metadata fields - common characteristics of automated malicious document creation.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
// directly attached PDF
any(filter(attachments, .file_type == "pdf"),
(
// table of contents detection
(
any(file.explode(.),
strings.contains(.scan.ocr.raw, 'TABLE OF CONTEN')
)
// the Table of contents can be on another page
and any(file.explode(.),
regex.icontains(.scan.ocr.raw,
'(?:[\r\n]|^)+(?:\s*1\s*(?:\.|:))?\s*Introduction'
)
or strings.icontains(.scan.ocr.raw, 'marked in red')
)
)
or (
any(file.explode(.),
any(.scan.strings.strings,
// heading of sections within observed documents
any([
'Employee Acknowledgement',
'Document Summary',
'appraisal overview',
'accessing full appraisal',
],
.. =~ .
)
)
// or links to free subdomain host
or any(.scan.url.urls,
.domain.root_domain in $free_subdomain_hosts
and .domain.subdomain is not null
// exclude sources of potential FPs
and .domain.root_domain not in ("atlassian.net")
)
)
)
)
and (
(
(
strings.icontains(beta.parse_exif(.).creator, 'HeadlessChrome')
or strings.icontains(beta.parse_exif(.).creator, 'Chromium')
)
and strings.icontains(beta.parse_exif(.).producer, 'Skia/PDF')
)
or (
any(beta.parse_exif(.).fields,
.key == "Creator"
and (.value == "" or strings.istarts_with(.value, 'wkhtmltopdf'))
)
and any(beta.parse_exif(.).fields,
.key == "Title"
and (
.value == ""
// company handbook
or .value in ('Company HandBook')
// appraisal themes
or strings.icontains(.value,
'Employee Performance Appraisal'
)
)
)
and strings.istarts_with(beta.parse_exif(.).producer, 'QT ')
)
)
)
// or within an attached EML
or any(filter(attachments,
.content_type == "message/rfc822" or .file_extension == "eml"
),
any(filter(file.parse_eml(.).attachments, .file_type == "pdf"),
(
// table of contents detection
(
any(file.explode(.),
strings.contains(.scan.ocr.raw, 'TABLE OF CONTEN')
)
// the Table of contents can be on another page
and any(file.explode(.),
regex.icontains(.scan.ocr.raw,
'(?:[\r\n]|^)+(?:\s*1\s*(?:\.|:))?\s*Introduction'
)
or strings.icontains(.scan.ocr.raw, 'marked in red')
)
)
or (
any(file.explode(.),
any(.scan.strings.strings,
// heading of sections within observed documents
any([
'Employee Acknowledgement',
'Document Summary',
'appraisal overview',
'accessing full appraisal',
],
.. =~ .
)
)
// or links to free subdomain host
or any(.scan.url.urls,
.domain.root_domain in $free_subdomain_hosts
and .domain.subdomain is not null
)
)
)
)
and (
(
(
strings.icontains(beta.parse_exif(.).creator,
'HeadlessChrome'
)
or strings.icontains(beta.parse_exif(.).creator, 'Chromium')
)
and strings.icontains(beta.parse_exif(.).producer, 'Skia/PDF')
)
or (
any(beta.parse_exif(.).fields,
.key == "Creator"
and (
.value == ""
or strings.istarts_with(.value, 'wkhtmltopdf')
)
)
and any(beta.parse_exif(.).fields,
.key == "Title"
and (
.value == ""
// company handbook
or .value in ('Company HandBook')
// appraisal themes
or strings.icontains(.value,
'Employee Performance Appraisal'
)
)
)
and strings.istarts_with(beta.parse_exif(.).producer, 'QT ')
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects PDF documents containing a table of contents that were generated using HeadlessChrome, Chromium with Skia/PDF, or QT with empty metadata fields - common characteristics of automated malicious document creation.
- inbound message
any of:
any of
filter(attachments)where all hold:any of:
all of:
any of
file.explode(.)where:- .scan.ocr.raw contains 'TABLE OF CONTEN'
any of
file.explode(.)where any holds:- .scan.ocr.raw matches '(?:[\\r\\n]|^)+(?:\\s*1\\s*(?:\\.|:))?\\s*Introduction'
- .scan.ocr.raw contains 'marked in red'
any of
file.explode(.)where any holds:any of
.scan.strings.stringswhere:any of
['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal']where:- . is .
any of
.scan.url.urlswhere all hold:- .domain.root_domain in $free_subdomain_hosts
- .domain.subdomain is set
- .domain.root_domain not in ('atlassian.net')
any of:
all of:
any of:
- beta.parse_exif(.).creator contains 'HeadlessChrome'
- beta.parse_exif(.).creator contains 'Chromium'
- beta.parse_exif(.).producer contains 'Skia/PDF'
all of:
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Creator'
any of:
- .value is ''
- .value starts with 'wkhtmltopdf'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Title'
any of:
- .value is ''
- .value in ('Company HandBook')
- .value contains 'Employee Performance Appraisal'
- beta.parse_exif(.).producer starts with 'QT '
any of
filter(attachments)where:any of
filter(...)where all hold:any of:
all of:
any of
file.explode(.)where:- .scan.ocr.raw contains 'TABLE OF CONTEN'
any of
file.explode(.)where any holds:- .scan.ocr.raw matches '(?:[\\r\\n]|^)+(?:\\s*1\\s*(?:\\.|:))?\\s*Introduction'
- .scan.ocr.raw contains 'marked in red'
any of
file.explode(.)where any holds:any of
.scan.strings.stringswhere:any of
['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal']where:- . is .
any of
.scan.url.urlswhere all hold:- .domain.root_domain in $free_subdomain_hosts
- .domain.subdomain is set
any of:
all of:
any of:
- beta.parse_exif(.).creator contains 'HeadlessChrome'
- beta.parse_exif(.).creator contains 'Chromium'
- beta.parse_exif(.).producer contains 'Skia/PDF'
all of:
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Creator'
any of:
- .value is ''
- .value starts with 'wkhtmltopdf'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Title'
any of:
- .value is ''
- .value in ('Company HandBook')
- .value contains 'Employee Performance Appraisal'
- beta.parse_exif(.).producer starts with 'QT '
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: beta.parse_exif, file.explode, file.parse_eml, regex.icontains, strings.contains, strings.icontains, strings.istarts_with. Reference lists: $free_subdomain_hosts.
Indicators matched (21)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.contains | substring | TABLE OF CONTEN |
regex.icontains | regex | (?:[\r\n]|^)+(?:\s*1\s*(?:\.|:))?\s*Introduction |
strings.icontains | substring | marked in red |
strings.icontains | substring | HeadlessChrome |
strings.icontains | substring | Chromium |
strings.icontains | substring | Skia/PDF |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | Creator |
beta.parse_exif(filter(attachments)[]).fields[].value | equals | |
strings.istarts_with | prefix | wkhtmltopdf |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | Title |
beta.parse_exif(filter(attachments)[]).fields[].value | member | Company HandBook |
9 more
strings.icontains | substring | Employee Performance Appraisal |
strings.istarts_with | prefix | QT |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
file.parse_eml(filter(attachments)[]).attachments[].file_type | equals | pdf |
beta.parse_exif(filter(...)[]).fields[].key | equals | Creator |
beta.parse_exif(filter(...)[]).fields[].value | equals | |
beta.parse_exif(filter(...)[]).fields[].key | equals | Title |
beta.parse_exif(filter(...)[]).fields[].value | member | Company HandBook |
Stages and Predicates
Stage 1: mql_rule
and
or
any(filter(attachments))
any(filter(...))
and
or
and
any(beta.parse_exif(filter(...)).fields)
and
or
beta.parse_exif(filter(...)[]).fields[].value contains "Employee Performance Appraisal"
beta.parse_exif(filter(...)[]).fields[].value eq ""
beta.parse_exif(filter(...)[]).fields[].value eq "Company HandBook"
beta.parse_exif(filter(...)[]).fields[].key eq "Title"
any(beta.parse_exif(filter(...)).fields)
and
or
beta.parse_exif(filter(...)[]).fields[].value eq ""
beta.parse_exif(filter(...)[]).fields[].value starts_with "wkhtmltopdf"
beta.parse_exif(filter(...)[]).fields[].key eq "Creator"
beta.parse_exif(filter(...)[]).producer starts_with "QT "
and
or
beta.parse_exif(filter(...)[]).creator contains "Chromium"
beta.parse_exif(filter(...)[]).creator contains "HeadlessChrome"
beta.parse_exif(filter(...)[]).producer contains "Skia/PDF"
or
any(file.explode(filter(...)))
or
any(file.explode(filter(...)).scan.strings.strings)
any(['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal'])
file.explode(filter(...)[])[].scan.strings.strings[] cross_field_compare "['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal']"
any(file.explode(filter(...)).scan.url.urls)
and
file.explode(filter(...)[])[].scan.url.urls[].domain.subdomain is_not_null
macro "file.explode(filter(...)[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
and
any(file.explode(filter(...)))
or
file.explode(filter(...)[])[].scan.ocr.raw contains "marked in red"
file.explode(filter(...)[])[].scan.ocr.raw regex_match "(?:[\\r\\n]|^)+(?:\\s*1\\s*(?:\\.|:))?\\s*Introduction"
any(file.explode(filter(...)))
file.explode(filter(...)).scan.ocr.raw contains "TABLE OF CONTEN"
any(filter(attachments))
and
or
any(file.explode(filter(attachments)))
or
any(file.explode(filter(attachments)).scan.url.urls)
and
not
file.explode(filter(attachments)[])[].scan.url.urls[].domain.root_domain eq "atlassian.net"
file.explode(filter(attachments)[])[].scan.url.urls[].domain.subdomain is_not_null
macro "file.explode(filter(attachments)[])[].scan.url.urls[].domain.root_domain in free_subdomain_hosts"
any(file.explode(filter(attachments)).scan.strings.strings)
any(['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal'])
file.explode(filter(attachments)[])[].scan.strings.strings[] cross_field_compare "['Employee Acknowledgement', 'Document Summary', 'appraisal overview', 'accessing full appraisal']"
and
any(file.explode(filter(attachments)))
or
file.explode(filter(attachments)[])[].scan.ocr.raw contains "marked in red"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "(?:[\\r\\n]|^)+(?:\\s*1\\s*(?:\\.|:))?\\s*Introduction"
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.ocr.raw contains "TABLE OF CONTEN"
or
and
any(beta.parse_exif(filter(attachments)).fields)
and
or
beta.parse_exif(filter(attachments)[]).fields[].value contains "Employee Performance Appraisal"
beta.parse_exif(filter(attachments)[]).fields[].value eq ""
beta.parse_exif(filter(attachments)[]).fields[].value eq "Company HandBook"
beta.parse_exif(filter(attachments)[]).fields[].key eq "Title"
any(beta.parse_exif(filter(attachments)).fields)
and
or
beta.parse_exif(filter(attachments)[]).fields[].value eq ""
beta.parse_exif(filter(attachments)[]).fields[].value starts_with "wkhtmltopdf"
beta.parse_exif(filter(attachments)[]).fields[].key eq "Creator"
beta.parse_exif(filter(attachments)[]).producer starts_with "QT "
and
or
beta.parse_exif(filter(attachments)[]).creator contains "Chromium"
beta.parse_exif(filter(attachments)[]).creator contains "HeadlessChrome"
beta.parse_exif(filter(attachments)[]).producer contains "Skia/PDF"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: SVG file execution
#Detects file execution attempts in SVG files. ActiveXObject is used to invoke WScript.Shell and run a program.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension =~ "svg"
or .file_extension in $file_extensions_common_archives
or .file_type == "svg"
)
and any(file.explode(.),
.file_extension == "svg"
// Author Matt harr0ey @harr0ey
// Topic: SVG file Execution
// WScript inside SVG
// <script language="JScript">
// <![CDATA[
// var r = new ActiveXObject("WScript.Shell").Run("calc.exe")
// ]]>
// </script>
and any(.scan.strings.strings,
strings.icontains(., "ActiveXObject")
)
and any(.scan.strings.strings,
strings.icontains(., "WScript.Shell")
)
and any(.scan.strings.strings,
strings.like(., "*Run*", "*Execute*")
)
)
)
Detection logic
Scope: inbound message.
Detects file execution attempts in SVG files. ActiveXObject is used to invoke WScript.Shell and run a program.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'svg'
- .file_extension in $file_extensions_common_archives
- .file_type is 'svg'
any of
file.explode(.)where all hold:- .file_extension is 'svg'
any of
.scan.strings.stringswhere:- . contains 'ActiveXObject'
any of
.scan.strings.stringswhere:- . contains 'WScript.Shell'
any of
.scan.strings.stringswhere:. matches any of 2 patterns
*Run**Execute*
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, strings.icontains, strings.like. Reference lists: $file_extensions_common_archives.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | svg |
attachments[].file_type | equals | svg |
file.explode(attachments[])[].file_extension | equals | svg |
strings.icontains | substring | ActiveXObject |
strings.icontains | substring | WScript.Shell |
strings.like | substring | *Run* |
strings.like | substring | *Execute* |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
or
file.explode(attachments[])[].scan.strings.strings[] match "Execute"
file.explode(attachments[])[].scan.strings.strings[] match "Run"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "ActiveXObject"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings contains "WScript.Shell"
file.explode(attachments[])[].file_extension eq "svg"
or
attachments.file_extension eq "svg"
attachments.file_type eq "svg"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: SVG file with HTML entity encoded href attributes
#Detects SVG file attachments containing href attributes with three or more consecutive HTML numeric entity references, a technique used to obfuscate malicious URLs and evade security scanning.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | Evasion, HTML smuggling |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension == "svg"
or .content_type in ("image/svg+xml")
or .file_type == "svg"
)
// href value starting with 3+ HTML numeric entity references
and regex.icontains(file.parse_text(.,
encodings=[
"ascii",
"utf8",
"utf16-le"
]
).text,
'href\s*=\s*["\x27]\s*(?:?[0-9a-f]+;\s*){3,}'
)
)
Detection logic
Scope: inbound message.
Detects SVG file attachments containing href attributes with three or more consecutive HTML numeric entity references, a technique used to obfuscate malicious URLs and evade security scanning.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'svg'
- .content_type in ('image/svg+xml')
- .file_type is 'svg'
- file.parse_text(., encodings=['ascii', 'utf8', 'utf16-le']).text matches 'href\\s*=\\s*["\\x27]\\s*(?:?[0-9a-f]+;\\s*){3,}'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.parse_text, regex.icontains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | svg |
attachments[].content_type | member | image/svg+xml |
attachments[].file_type | equals | svg |
regex.icontains | regex | href\s*=\s*["\x27]\s*(?:?[0-9a-f]+;\s*){3,} |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type eq "image/svg+xml"
attachments.file_extension eq "svg"
attachments.file_type eq "svg"
file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text regex_match "href\\s*=\\s*[\"\\x27]\\s*(?:?[0-9a-f]+;\\s*){3,}"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: SVG file with hyperlinks and cursor styling
#Detects inbound messages containing SVG attachments that include clickable hyperlink elements and CSS pointer cursor styling, which may be used to deceive recipients into clicking malicious links disguised as legitimate images.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Image as content |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension == "svg"
or .content_type in ("image/svg+xml")
or .file_type == "svg"
)
and any(file.explode(.), any(.scan.xml.tags, . == "a"))
and regex.icontains(file.parse_text(., encodings=["ascii", "utf8"]).text,
'cursor\s*=\s*["\x27]pointer'
)
)
Detection logic
Scope: inbound message.
Detects inbound messages containing SVG attachments that include clickable hyperlink elements and CSS pointer cursor styling, which may be used to deceive recipients into clicking malicious links disguised as legitimate images.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension is 'svg'
- .content_type in ('image/svg+xml')
- .file_type is 'svg'
any of
file.explode(.)where:any of
.scan.xml.tagswhere:- . is 'a'
- file.parse_text(., encodings=['ascii', 'utf8']).text matches 'cursor\\s*=\\s*["\\x27]pointer'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, type.inbound. Sensors: file.explode, file.parse_text, regex.icontains.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | svg |
attachments[].content_type | member | image/svg+xml |
attachments[].file_type | equals | svg |
file.explode(attachments[])[].scan.xml.tags[] | equals | a |
regex.icontains | regex | cursor\s*=\s*["\x27]pointer |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.xml.tags)
file.explode(attachments).scan.xml.tags eq "a"
or
attachments.content_type eq "image/svg+xml"
attachments.file_extension eq "svg"
attachments.file_type eq "svg"
file.parse_text(attachments[], encodings=['ascii', 'utf8']).text regex_match "cursor\\s*=\\s*[\"\\x27]pointer"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: SVG files with evasion elements
#This rule identifies incoming SVG vector graphics files containing specific patterns: circle elements combined with either embedded images, hyperlinks, QR codes, or filenames that match recipient information. Limited to three attachments. SVG circle elements have been used to obfuscate QR codes and bypass automated QR code scanning methods.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
| Tactics and techniques | QR code, Image as content, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) < 4
and any(attachments,
(
.file_extension == "svg"
or .content_type in ("image/svg+xml")
or .file_type == "svg"
)
and any(file.explode(.),
any(.scan.xml.tags, . == "circle")
and 1 of (
any(.scan.xml.tags, . in ("image", "a")),
.scan.qr.data is not null,
any(recipients.to,
strings.icontains(..file_name, .email.local_part)
),
any(recipients.to,
strings.icontains(..file_name, .email.domain.sld)
)
)
)
)
Detection logic
Scope: inbound message.
This rule identifies incoming SVG vector graphics files containing specific patterns: circle elements combined with either embedded images, hyperlinks, QR codes, or filenames that match recipient information. Limited to three attachments. SVG circle elements have been used to obfuscate QR codes and bypass automated QR code scanning methods.
- inbound message
- length(attachments) < 4
any of
attachmentswhere all hold:any of:
- .file_extension is 'svg'
- .content_type in ('image/svg+xml')
- .file_type is 'svg'
any of
file.explode(.)where all hold:any of
.scan.xml.tagswhere:- . is 'circle'
at least 1 of:
any of
.scan.xml.tagswhere:- . in ('image', 'a')
- .scan.qr.data is set
any of
recipients.towhere:- strings.icontains(.file_name)
any of
recipients.towhere:- strings.icontains(.file_name)
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.local_part, type.inbound. Sensors: file.explode, strings.icontains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | svg |
attachments[].content_type | member | image/svg+xml |
attachments[].file_type | equals | svg |
file.explode(attachments[])[].scan.xml.tags[] | equals | circle |
file.explode(attachments[])[].scan.xml.tags[] | member | image |
file.explode(attachments[])[].scan.xml.tags[] | member | a |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
or
any(file.explode(attachments).scan.xml.tags)
file.explode(attachments).scan.xml.tags in ["a", "image"]
any(recipients.to)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].file_name)"
file.explode(attachments[])[].scan.qr.data is_not_null
any(file.explode(attachments).scan.xml.tags)
file.explode(attachments).scan.xml.tags eq "circle"
or
attachments.content_type eq "image/svg+xml"
attachments.file_extension eq "svg"
attachments.file_type eq "svg"
attachments length_compare "4"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: TAR file with RAR type
#Detects messages with TAR file extensions that are actually RAR file types. This mismatch between file extension and actual file type may indicate an evasion technique.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments, .file_extension =~ "tar" and .file_type =~ "rar")
Detection logic
Scope: inbound message.
Detects messages with TAR file extensions that are actually RAR file types. This mismatch between file extension and actual file type may indicate an evasion technique.
- inbound message
any of
attachmentswhere all hold:- .file_extension is 'tar'
- .file_type is 'rar'
Inspects: attachments[].file_extension, attachments[].file_type, type.inbound.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | tar |
attachments[].file_type | equals | rar |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
attachments.file_extension eq "tar"
attachments.file_type eq "rar"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Targeted DOCX with personalized recipient acknowledgement lure
#Detects inbound messages with a DOCX attachment containing a quarterly date reference, specific STATUS and ACKNOWLEDGEMENT formatting patterns, and a personalized salutation where the recipient's name or local email part is dynamically embedded in the document XML.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "docx"),
any(filter(file.explode(.), .file_name == "word/document.xml"),
// doc xml has a QX 2026 type date
regex.contains(.scan.strings.raw, '<w:t>Q[1-4]\S202[5-9]<\/w:t>')
// and a couple of the terms we've seen in the document with specific spacing reqs
and strings.contains(.scan.strings.raw,
'<w:t xml:space="preserve">STATUS </w:t>'
)
and strings.contains(.scan.strings.raw,
'<w:t xml:space="preserve">ACKNOWLEDGEMENT </w:t>'
)
// and doc xml has some reference to the user's name in there too?
and any(regex.extract(.scan.strings.raw,
'<w:t xml:space="preserve">Dear </w:t></w:r><w:r><w:rPr><w:b /><w:bCs /><w:color w:val="[a-f0-9]{6}" /><w:sz w:val="[0-9]{1,3}" /><w:szCs w:val="[0-9]{1,3}" /></w:rPr><w:t>(?P<name>.*?)</w:t></w:r>'
),
any(recipients.to,
(
..named_groups["name"] =~ .email.local_part
or ..named_groups["name"] =~ .display_name
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects inbound messages with a DOCX attachment containing a quarterly date reference, specific STATUS and ACKNOWLEDGEMENT formatting patterns, and a personalized salutation where the recipient's name or local email part is dynamically embedded in the document XML.
- inbound message
any of
filter(attachments)where:any of
filter(...)where all hold:- .scan.strings.raw matches '<w:t>Q[1-4]\\S202[5-9]<\\/w:t>'
- .scan.strings.raw contains '<w:t xml:space="preserve">STATUS </w:t>'
- .scan.strings.raw contains '<w:t xml:space="preserve">ACKNOWLEDGEMENT </w:t>'
any of
regex.extract(.scan.strings.raw)where:any of
recipients.towhere any holds:- .named_groups['name'] is .email.local_part
- .named_groups['name'] is .display_name
Inspects: attachments[].file_type, recipients.to, recipients.to[].display_name, recipients.to[].email.local_part, type.inbound. Sensors: file.explode, regex.contains, regex.extract, strings.contains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | docx |
file.explode(filter(attachments)[])[].file_name | equals | word/document.xml |
regex.contains | regex | <w:t>Q[1-4]\S202[5-9]<\/w:t> |
strings.contains | substring | <w:t xml:space="preserve">STATUS </w:t> |
strings.contains | substring | <w:t xml:space="preserve">ACKNOWLEDGEMENT </w:t> |
regex.extract | regex | <w:t xml:space="preserve">Dear </w:t></w:r><w:r><w:rPr><w:b /><w:bCs /><w:color w:val="[a-f0-9]{6}" /><w:sz w:val="[0-9]{1,3}" /><w:szCs w:val="[0-9]{1,3}" /></w:rPr><w:t>(?P<name>.*?)</w:t></w:r> |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(filter(...))
and
any(regex.extract(filter(...).scan.strings.raw))
any(recipients.to)
or
regex.extract(filter(...)[].scan.strings.raw)[].named_groups['name'] cross_field_compare "recipients.to.display_name"
regex.extract(filter(...)[].scan.strings.raw)[].named_groups['name'] cross_field_compare "recipients.to.email.local_part"
filter(...).scan.strings.raw contains "<w:t xml:space=\"preserve\">ACKNOWLEDGEMENT </w:t>"
filter(...).scan.strings.raw contains "<w:t xml:space=\"preserve\">STATUS </w:t>"
filter(...).scan.strings.raw regex_match "<w:t>Q[1-4]\\S202[5-9]<\\/w:t>"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Uncommon compressed file
#Use if passing compressed or archive files is not typical behavior in your organization. This behavior has been observed in a number of phishing campaigns.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Credential Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in ('tar', 'iso', 'img', 'cab', 'gadget', 'uue')
)
Detection logic
Scope: inbound message.
Use if passing compressed or archive files is not typical behavior in your organization. This behavior has been observed in a number of phishing campaigns.
- inbound message
any of
attachmentswhere:- .file_extension in ('tar', 'iso', 'img', 'cab', 'gadget', 'uue')
Inspects: attachments[].file_extension, type.inbound.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | tar |
attachments[].file_extension | member | iso |
attachments[].file_extension | member | img |
attachments[].file_extension | member | cab |
attachments[].file_extension | member | gadget |
attachments[].file_extension | member | uue |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
attachments.file_extension in ["cab", "gadget", "img", "iso", "tar", "uue"]
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: USDA bid invitation impersonation
#Detects messages claiming to be from USDA containing bid invitations with macro-enabled attachments or PDFs. Validates USDA-related content through OCR and natural language analysis.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Impersonation: Brand, PDF, Macros, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) == 1
and all(attachments,
(.file_extension in~ $file_extensions_macros or .file_type == "pdf")
and any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).entities,
strings.icontains(.text, "Agriculture")
)
)
)
and strings.icontains(body.current_thread.text, "bid")
and (
strings.icontains(subject.subject, 'invitation to bid')
or any(attachments, strings.icontains(.file_name, 'usda'))
)
and strings.icontains(sender.email.domain.domain, "usda")
and any(ml.nlu_classifier(body.current_thread.text).entities,
.text == "usda" and .name in ("sender", "org")
)
Detection logic
Scope: inbound message.
Detects messages claiming to be from USDA containing bid invitations with macro-enabled attachments or PDFs. Validates USDA-related content through OCR and natural language analysis.
- inbound message
- length(attachments) is 1
all of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_type is 'pdf'
any of
file.explode(.)where:any of
ml.nlu_classifier(.scan.ocr.raw).entitieswhere:- .text contains 'Agriculture'
- body.current_thread.text contains 'bid'
any of:
- subject.subject contains 'invitation to bid'
any of
attachmentswhere:- .file_name contains 'usda'
- sender.email.domain.domain contains 'usda'
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere all hold:- .text is 'usda'
- .name in ('sender', 'org')
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, sender.email.domain.domain, subject.subject, type.inbound. Sensors: file.explode, ml.nlu_classifier, strings.icontains. Reference lists: $file_extensions_macros.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.icontains | substring | Agriculture |
strings.icontains | substring | bid |
strings.icontains | substring | invitation to bid |
strings.icontains | substring | usda |
ml.nlu_classifier(body.current_thread.text).entities[].text | equals | usda |
ml.nlu_classifier(body.current_thread.text).entities[].name | member | sender |
ml.nlu_classifier(body.current_thread.text).entities[].name | member | org |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
attachments.file_name contains "usda"
subject.subject contains "invitation to bid"
any(ml.nlu_classifier(body.current_thread.text).entities)
and
ml.nlu_classifier(body.current_thread.text).entities.name in ["org", "sender"]
ml.nlu_classifier(body.current_thread.text).entities.text eq "usda"
attachments length_compare "1"
body.current_thread.text contains "bid"
sender.email.domain.domain contains "usda"
type.inbound eq "true"
macro "all(attachments)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains value:"bid" |
sender.email.domain.domain | contains |
| field:"sender.email.domain.domain" kind:contains value:"usda" |
subject.subject | contains |
| field:"subject.subject" kind:contains value:"invitation to bid" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Web files with suspicious comments
#Detects HTML or SVG files under 100KB that contain duplicate or padding text in the form of literary quotes or common sayings within code comments.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | HTML smuggling, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
(
.file_type in ("html", "svg")
or .file_extension in ("html", "xhtml", "mhtml", "svg")
or .content_type in ("text/html", "text/plain")
)
and .size < 100000
)
and (
(
// targeting comments that pad the file with quotes from literature
// examples: "// Echoes of the past linger in silence.", "// The wind whispered secrets unknown.", "// Shadows tell stories in the dark."
// count all HTML code comments that match our pattern
regex.count(file.parse_text(.).text, '// [A-Z][ a-z ]+\.') /
// divide by the count of all UNIQUE HTML code comments that match our pattern
length(distinct(regex.extract(file.parse_text(.).text,
'// [A-Z][ a-z ]+\.'
),
.full_match
)
)
// at least 50% of the comments are duplicates
>= 2
)
or (
// targeting comments that pad the file with sayings
// examples: "<!-- <span> No gain without pain. </span> -->", "<!-- <p> Beauty is only skin deep. </p> -->", "<!-- <span> Actions speak louder than words. </span> -->"
regex.count(file.parse_text(.).text,
'<!-- +(<[a-z]+>)? [A-Z][ a-z ]+\. (</[a-z]+>)? +-->'
)
) > 2
or (
// targeting comments inside hidden HTML elements
// example: "<h1 style="display:none;"> Self-confidence inspires others to believe in you. </h1>"
regex.count(file.parse_text(.).text,
'<[a-z0-9]+ style="display:none;">(<[a-z]+>)? [A-Z].*\. </[a-z0-9]+>'
)
) > 2
)
)
Detection logic
Scope: inbound message.
Detects HTML or SVG files under 100KB that contain duplicate or padding text in the form of literary quotes or common sayings within code comments.
- inbound message
any of
attachmentswhere all hold:all of:
any of:
- .file_type in ('html', 'svg')
- .file_extension in ('html', 'xhtml', 'mhtml', 'svg')
- .content_type in ('text/html', 'text/plain')
- .size < 100000
any of:
- regex.count(file.parse_text(.).text) / length(distinct(regex.extract(file.parse_text(.).text, '// [A-Z][ a-z ]+\\.'), .full_match)) ≥ 2
- regex.count(file.parse_text(.).text, '<!-- +(<[a-z]+>)? [A-Z][ a-z ]+\\. (</[a-z]+>)? +-->') > 2
- regex.count(file.parse_text(.).text, '<[a-z0-9]+ style="display:none;">(<[a-z]+>)? [A-Z].*\\. </[a-z0-9]+>') > 2
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.parse_text, regex.count.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | member | html |
attachments[].file_type | member | svg |
attachments[].file_extension | member | html |
attachments[].file_extension | member | xhtml |
attachments[].file_extension | member | mhtml |
attachments[].file_extension | member | svg |
attachments[].content_type | member | text/html |
attachments[].content_type | member | text/plain |
regex.count | regex | <!-- +(<[a-z]+>)? [A-Z][ a-z ]+\. (</[a-z]+>)? +--> |
regex.count | regex | <[a-z0-9]+ style="display:none;">(<[a-z]+>)? [A-Z].*\. </[a-z0-9]+> |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
attachments.content_type in ["text/html", "text/plain"]
attachments.file_extension in ["html", "mhtml", "svg", "xhtml"]
attachments.file_type in ["html", "svg"]
or
regex.count func_call "regex.count(file.parse_text(attachments[]).text, \"<!-- +(<[a-z]+>)? [A-Z][ a-z ]+\\. (</[a-z]+>)? +-->\") > 2"
regex.count func_call "regex.count(file.parse_text(attachments[]).text, \"<[a-z0-9]+ style=\"display:none;\">(<[a-z]+>)? [A-Z].*\\. </[a-z0-9]+>\") > 2"
macro "(regex.count(file.parse_text(attachments[]).text) / length(distinct(regex.extract(file.parse_text(attachments[]).text, '// [A-Z][ a-z ]+\\\\.'), attachments[].full_match))) >= 2"
attachments.size lt "100000"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: WinRAR CVE-2025-8088 exploitation
#Detects attempts to exploit CVE-2025-8088 via attached RAR files
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Exploit, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
// its a rar file
(
.content_type == "application/x-rar-compressed"
or .file_extension == "rar"
or .file_type == "rar"
)
// less than 10 meg
and .size < 10000000
// explode it
and any(file.explode(.),
// contains a yara match
any(.scan.yara.matches, .name == "WinRAR_CVE_2025_8088")
)
)
Detection logic
Scope: inbound message.
Detects attempts to exploit CVE-2025-8088 via attached RAR files
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'application/x-rar-compressed'
- .file_extension is 'rar'
- .file_type is 'rar'
- .size < 10000000
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'WinRAR_CVE_2025_8088'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: file.explode.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | application/x-rar-compressed |
attachments[].file_extension | equals | rar |
attachments[].file_type | equals | rar |
file.explode(attachments[])[].scan.yara.matches[].name | equals | WinRAR_CVE_2025_8088 |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.yara.matches)
file.explode(attachments).scan.yara.matches.name eq "WinRAR_CVE_2025_8088"
or
attachments.content_type eq "application/x-rar-compressed"
attachments.file_extension eq "rar"
attachments.file_type eq "rar"
attachments.size lt "10000000"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: XLSX file with suspicious print titles metadata
#Detects XLSX attachments containing EXIF metadata with suspicious TitlesOfParts fields that follow a specific pattern combining 'Company_Name' with extracted values and 'Print_Titles', potentially indicating malicious document preparation.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(filter(attachments, .file_type == "xlsx"),
// get the TitleOfParts (Excel Docs this is Worksheet names)
// https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oi29500/de32de14-9573-46f3-9f38-19659e3a8d9a
any(filter(beta.parse_exif(.).fields, .key == "TitlesOfParts"),
// extract the first sheet name
any(regex.iextract(.value, '^\[\"(?P<first_sheet>[^\"]+)\"'),
// check that the first sheet name is observed in the last sheet name with !print_title and comes after a sheet named "Company_Name"
strings.ends_with(..value,
strings.concat("Company_Name\",\"",
.named_groups["first_sheet"],
'!Print_Titles"]'
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects XLSX attachments containing EXIF metadata with suspicious TitlesOfParts fields that follow a specific pattern combining 'Company_Name' with extracted values and 'Print_Titles', potentially indicating malicious document preparation.
- inbound message
any of
filter(attachments)where:any of
filter(...)where:any of
regex.iextract(.value)where:- strings.ends_with(.value)
Inspects: attachments[].file_type, type.inbound. Sensors: beta.parse_exif, regex.iextract, strings.concat, strings.ends_with.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | xlsx |
beta.parse_exif(filter(attachments)[]).fields[].key | equals | TitlesOfParts |
regex.iextract | regex | ^\[\"(?P<first_sheet>[^\"]+)\" |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
any(filter(...))
any(regex.iextract(filter(...).value))
strings.ends_with func_call "strings.ends_with(filter(...)[].value)"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: Zip exploiting CVE-2023-38831 (unsolicited)
#A Zip attachment that exhibits attributes required to exploit CVE-2023-38831, a vulnerability in WinRAR (prior to 6.23).
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in $file_extensions_common_archives and
any(file.explode(.),
(
.depth == 0 and
any(.scan.zip.all_paths,
regex.match(.,
// zip contains a path with spaces and file extensions
// lure.pdf /lure.pdf .cmd
//
// /= Initial file name (including any spaces)
// |
// | /= Space
// | |
// | | /= Folder
// | | |
// | | | /= Repeated file name
// | | | |
// | | | | /= Space
// | | | | |
// | | | | | /= Real script ending
// | | | | | |
'.+\.\w+\s\/.+\.\w+\s\.\w+'
)
)
) and
(
// One file name is present in another, e.g.
// delivrto.pdf
// delivrto.pdf /delivrto.pdf .cmd
any(.scan.zip.all_paths,
any(..scan.zip.all_paths,
. != .. and
strings.starts_with(., ..)
)
)
)
)
)
and (
(
sender.email.domain.root_domain in $free_email_providers
and sender.email.email not in $recipient_emails
)
or (
sender.email.domain.root_domain not in $free_email_providers
and sender.email.domain.domain not in $recipient_domains
)
)
Detection logic
Scope: inbound message.
A Zip attachment that exhibits attributes required to exploit CVE-2023-38831, a vulnerability in WinRAR (prior to 6.23).
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where all hold:all of:
- .depth is 0
any of
.scan.zip.all_pathswhere:- . matches '.+\\.\\w+\\s\\/.+\\.\\w+\\s\\.\\w+'
any of
.scan.zip.all_pathswhere:any of
.scan.zip.all_pathswhere all hold:- . is not .
- strings.starts_with(.)
any of:
all of:
- sender.email.domain.root_domain in $free_email_providers
- sender.email.email not in $recipient_emails
all of:
- sender.email.domain.root_domain not in $free_email_providers
- sender.email.domain.domain not in $recipient_domains
Inspects: attachments[].file_extension, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, regex.match, strings.starts_with. Reference lists: $file_extensions_common_archives, $free_email_providers, $recipient_domains, $recipient_emails.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
regex.match | regex | .+\.\w+\s\/.+\.\w+\s\.\w+ |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.zip.all_paths)
any(file.explode(attachments).scan.zip.all_paths)
and
file.explode(attachments[])[].scan.zip.all_paths[] cross_field_compare "file.explode(attachments[])[].scan.zip.all_paths[]"
strings.starts_with func_call "strings.starts_with(file.explode(attachments[])[].scan.zip.all_paths[])"
any(file.explode(attachments).scan.zip.all_paths)
file.explode(attachments).scan.zip.all_paths regex_match ".+\\.\\w+\\s\\/.+\\.\\w+\\s\\.\\w+"
file.explode(attachments[])[].depth eq "0"
macro "attachments[].file_extension in file_extensions_common_archives"
or
and
macro "sender.email.domain.domain not in recipient_domains"
macro "sender.email.domain.root_domain not in free_email_providers"
and
macro "sender.email.domain.root_domain in free_email_providers"
macro "sender.email.email not in recipient_emails"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: ZIP file with CVE-2026-0866 exploit
#Detects ZIP attachments containing exploits targeting CVE-2026-0866 vulnerability through YARA signature matching.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Exploit, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
any(filter(attachments, .file_type == "zip"),
any(file.explode(.),
any(.scan.yara.matches, .name in ("zip_cve_2026_0866"))
)
)
Detection logic
Detects ZIP attachments containing exploits targeting CVE-2026-0866 vulnerability through YARA signature matching.
any of filter(attachments) where:
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name in ('zip_cve_2026_0866')
Inspects: attachments[].file_type. Sensors: file.explode.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | zip |
file.explode(filter(attachments)[])[].scan.yara.matches[].name | member | zip_cve_2026_0866 |
Stages and Predicates
Stage 1: mql_rule
any(filter(attachments))
any(file.explode(filter(attachments)))
any(file.explode(filter(attachments)).scan.yara.matches)
file.explode(filter(attachments)).scan.yara.matches.name eq "zip_cve_2026_0866"Brand impersonation: Adobe (QR code)
#Detects messages using Adobe image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
(.file_type in $file_types_images or .file_type == "pdf")
and (
any(ml.logo_detect(.).brands,
.name == "Adobe" and .confidence in ("medium", "high")
)
or any(ml.logo_detect(file.message_screenshot()).brands,
.name == "Adobe"
)
or any(file.explode(.),
any(.scan.strings.strings,
regex.icontains(., "adobe (acrobat|sign)")
// negate PDF data, like "xmp:CreatorTool>Adobe Acrobat Pro (64-bit) 24.4.20272</xmp:CreatorTool>"
and not regex.icontains(.,
"(creatortool|producer|creator).{1,5}adobe acrobat"
)
)
)
)
)
or any(attachments,
.file_extension in $file_extensions_macros
and any(file.explode(.), .depth == 0 and .scan.docx.image_count > 0)
and any(file.explode(.),
any(.scan.strings.strings, strings.ilike(., "*adobe*"))
)
)
)
and any(attachments,
(
.file_type in $file_types_images
or .file_type == "pdf"
or .file_type in $file_extensions_macros
)
and (
any(file.explode(.),
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
or (
any(file.explode(.),
.scan.qr.type == "url"
// recipient email address is present in the URL, a common tactic used in credential phishing attacks
and (
any(recipients.to,
(
(
.email.domain.valid
and (
strings.icontains(..scan.qr.data, .email.email)
or any(strings.scan_base64(..scan.qr.data,
format="url"
),
strings.icontains(., ..email.email)
)
)
)
or strings.icontains(.display_name, "undisclosed")
)
)
// the recipients sld is in the senders display name
or any(recipients.to,
strings.icontains(sender.display_name,
.email.domain.sld
)
)
// the recipient local is in the body
or any(recipients.to,
strings.icontains(body.current_thread.text,
.email.local_part
)
)
// or the body is null
or body.current_thread.text is null
or body.current_thread.text == ""
// or the subject contains authentication/urgency verbiage
or regex.contains(subject.subject,
"(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
)
// high confidence cred theft in body
or any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence in ("high")
)
)
)
)
)
)
and (
not sender.email.domain.root_domain in (
"acrobat.com",
"adobecc.com",
"adobecces.com",
"adobeccstatic.com",
"adobe.com",
"adobeexchange.com",
"adobe-identity.com",
"adobe.io",
"adobejanus.com",
"adobelogin.com",
"adobe.net",
"adobeprojectm.com",
"adoberesources.net",
"adobesc.com",
"adobesign.com",
"adobestock.com",
"createjs.com",
"licensingstack.com",
"myportfolio.com",
"photoshop.com",
"typekit.com",
"typekit.net"
)
or not any(headers.hops,
.authentication_results.compauth.verdict is not null
and .authentication_results.compauth.verdict == "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 messages using Adobe image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
- inbound message
any of:
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
any of:
any of
ml.logo_detect(.).brandswhere all hold:- .name is 'Adobe'
- .confidence in ('medium', 'high')
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name is 'Adobe'
any of
file.explode(.)where:any of
.scan.strings.stringswhere all hold:- . matches 'adobe (acrobat|sign)'
not:
- . matches '(creatortool|producer|creator).{1,5}adobe acrobat'
any of
attachmentswhere all hold:- .file_extension in $file_extensions_macros
any of
file.explode(.)where all hold:- .depth is 0
- .scan.docx.image_count > 0
any of
file.explode(.)where:any of
.scan.strings.stringswhere:- . matches '*adobe*'
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
- .file_type in $file_extensions_macros
any of:
any of
file.explode(.)where all hold:- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
any of:
any of
recipients.towhere any holds:all of:
- .email.domain.valid
any of:
- strings.icontains(.scan.qr.data)
any of
strings.scan_base64(.scan.qr.data)where:- strings.icontains(.)
- .display_name contains 'undisclosed'
any of
recipients.towhere:- strings.icontains(sender.display_name)
any of
recipients.towhere:- strings.icontains(body.current_thread.text)
- body.current_thread.text is missing
- body.current_thread.text is ''
- subject.subject matches '(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)'
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence in ('high')
any of:
not:
- sender.email.domain.root_domain in ('acrobat.com', 'adobecc.com', 'adobecces.com', 'adobeccstatic.com', 'adobe.com', 'adobeexchange.com', 'adobe-identity.com', 'adobe.io', 'adobejanus.com', 'adobelogin.com', 'adobe.net', 'adobeprojectm.com', 'adoberesources.net', 'adobesc.com', 'adobesign.com', 'adobestock.com', 'createjs.com', 'licensingstack.com', 'myportfolio.com', 'photoshop.com', 'typekit.com', 'typekit.net')
not:
any of
headers.hopswhere all hold:- .authentication_results.compauth.verdict is set
- .authentication_results.compauth.verdict is 'pass'
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_extension, attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].authentication_results.compauth.verdict, 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.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, regex.contains, regex.icontains, strings.icontains, strings.ilike, strings.scan_base64. Reference lists: $file_extensions_macros, $file_types_images, $high_trust_sender_root_domains.
Indicators matched (15)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
ml.logo_detect(attachments[]).brands[].name | equals | Adobe |
ml.logo_detect(attachments[]).brands[].confidence | member | medium |
ml.logo_detect(attachments[]).brands[].confidence | member | high |
ml.logo_detect(file.message_screenshot()).brands[].name | equals | Adobe |
regex.icontains | regex | adobe (acrobat|sign) |
strings.ilike | substring | *adobe* |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
file.explode(attachments[])[].scan.qr.type | equals | url |
strings.icontains | substring | undisclosed |
body.current_thread.text | equals | |
3 more
regex.contains | regex | (Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):) |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | member | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
any(file.explode(attachments))
and
or
any(recipients.to)
or
and
or
any(strings.scan_base64(file.explode(attachments).scan.qr.data))
strings.icontains func_call "strings.icontains(strings.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"
recipients.to.display_name contains "undisclosed"
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(recipients.to)
strings.icontains func_call "strings.icontains(body.current_thread.text)"
any(recipients.to)
strings.icontains func_call "strings.icontains(sender.display_name)"
body.current_thread.text eq ""
body.current_thread.text is_null
subject.subject regex_match "(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
file.explode(attachments[])[].scan.qr.type eq "url"
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.ocr.raw regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.explode(attachments[])[].scan.ocr.raw regex_match "scan|camera"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
or
any(attachments)
and
or
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
and
not
file.explode(attachments[])[].scan.strings.strings[] regex_match "(creatortool|producer|creator).{1,5}adobe acrobat"
file.explode(attachments[])[].scan.strings.strings[] regex_match "adobe (acrobat|sign)"
any(ml.logo_detect(attachments).brands)
and
ml.logo_detect(attachments[]).brands[].confidence in ["high", "medium"]
ml.logo_detect(attachments[]).brands[].name eq "Adobe"
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name eq "Adobe"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_types_images"
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings match "adobe"
any(file.explode(attachments))
and
file.explode(attachments[])[].depth eq "0"
file.explode(attachments[])[].scan.docx.image_count gt "0"
macro "attachments[].file_extension in file_extensions_macros"
or
not
any(headers.hops)
and
headers.hops.authentication_results.compauth.verdict eq "pass"
headers.hops.authentication_results.compauth.verdict is_not_null
not
sender.email.domain.root_domain in ["acrobat.com", "adobe-identity.com", "adobe.com", "adobe.io", "adobe.net", "adobecc.com", "adobecces.com", "adobeccstatic.com", "adobeexchange.com", "adobejanus.com", "adobelogin.com", "adobeprojectm.com", "adoberesources.net", "adobesc.com", "adobesign.com", "adobestock.com", "createjs.com", "licensingstack.com", "myportfolio.com", "photoshop.com", "typekit.com", "typekit.net"]
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Brand impersonation: DocuSign (QR code)
#Detects messages using DocuSign image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(.file_type in $file_types_images or .file_type == "pdf")
and (
any(ml.logo_detect(.).brands,
.name == "DocuSign" and .confidence in ("medium", "high")
)
or any(ml.logo_detect(file.message_screenshot()).brands,
.name == "DocuSign"
)
)
and (
any(file.explode(.),
(
(
.scan.qr.type is not null
and regex.contains(.scan.qr.data, '\.')
)
or
// QR code language
(
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
)
// exclude images taken with mobile cameras and screenshots from android
and not any(.scan.exiftool.fields,
.key == "Model"
or (
.key == "Software"
and strings.starts_with(.value, "Android")
)
)
// exclude images taken with mobile cameras and screenshots from Apple
and not any(.scan.exiftool.fields,
.key == "DeviceManufacturer"
and .value == "Apple Computer Inc."
)
)
)
)
and not (
sender.email.domain.root_domain in ("docusign.net", "docusign.com")
and headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Detects messages using DocuSign image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
any of:
any of
ml.logo_detect(.).brandswhere all hold:- .name is 'DocuSign'
- .confidence in ('medium', 'high')
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name is 'DocuSign'
any of
file.explode(.)where all hold:any of:
all of:
- .scan.qr.type is set
- .scan.qr.data matches '\\.'
all of:
- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
not:
any of
.scan.exiftool.fieldswhere any holds:- .key is 'Model'
all of:
- .key is 'Software'
- .value starts with 'Android'
not:
any of
.scan.exiftool.fieldswhere all hold:- .key is 'DeviceManufacturer'
- .value is 'Apple Computer Inc.'
not:
all of:
- sender.email.domain.root_domain in ('docusign.net', 'docusign.com')
- headers.auth_summary.dmarc.pass
Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, regex.contains, regex.icontains, strings.starts_with. Reference lists: $file_types_images.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
ml.logo_detect(attachments[]).brands[].name | equals | DocuSign |
ml.logo_detect(attachments[]).brands[].confidence | member | medium |
ml.logo_detect(attachments[]).brands[].confidence | member | high |
ml.logo_detect(file.message_screenshot()).brands[].name | equals | DocuSign |
regex.contains | regex | \. |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
not
any(file.explode(attachments).scan.exiftool.fields)
or
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Software"
file.explode(attachments[])[].scan.exiftool.fields[].value starts_with "Android"
file.explode(attachments[])[].scan.exiftool.fields[].key eq "Model"
not
any(file.explode(attachments).scan.exiftool.fields)
and
file.explode(attachments[])[].scan.exiftool.fields[].key eq "DeviceManufacturer"
file.explode(attachments[])[].scan.exiftool.fields[].value eq "Apple Computer Inc."
or
and
file.explode(attachments[])[].scan.ocr.raw regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.explode(attachments[])[].scan.ocr.raw regex_match "scan|camera"
and
file.explode(attachments[])[].scan.qr.data regex_match "\\."
file.explode(attachments[])[].scan.qr.type is_not_null
or
any(ml.logo_detect(attachments).brands)
and
ml.logo_detect(attachments[]).brands[].confidence in ["high", "medium"]
ml.logo_detect(attachments[]).brands[].name eq "DocuSign"
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name eq "DocuSign"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_types_images"
not
and
headers.auth_summary.dmarc.pass eq "true"
sender.email.domain.root_domain in ["docusign.com", "docusign.net"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.auth_summary.dmarc.pass | eq | true | excludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true" |
sender.email.domain.root_domain | in | docusign.com, docusign.net | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"docusign.com" field:"sender.email.domain.root_domain" value:"docusign.net" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Brand impersonation: DocuSign branded attachment lure with no DocuSign links
#Detects DocuSign phishing messages with no DocuSign links, a DocuSign logo or verbage within an image or PDF attachment, from an untrusted sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
(
0 < length(attachments) <= 8
and length(filter(attachments, .file_type in $file_types_images)) > 0
)
or (
length(attachments) > 0
and all(attachments,
.file_type in $file_types_images
or .file_type == 'pdf'
or (
.file_extension == "ics"
or .content_type in ("text/calendar", "application/ics")
)
)
)
)
and (
// if there are links, ensure they are not docusign links
(
length(body.links) != 0
and any(body.links,
not strings.ilike(.href_url.domain.root_domain, "docusign.*")
)
)
// sometimes there are no body links and it's all in the PDF attachment
or length(body.links) == 0
)
and (
// check the image or pdf attachments for Docusign
any(filter(attachments,
.file_type in $file_types_images or .file_type == 'pdf'
),
(
any(ml.logo_detect(.).brands, .name == "DocuSign")
or any(file.explode(.),
strings.ilike(.scan.ocr.raw, "*DocuSign*")
and (
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence != "low"
)
or (
regex.icontains(.scan.ocr.raw,
"((re)?view|access|complete(d)?) document(s)?",
'[^d][^o][^cd][^ue]sign(?:\b|ature)',
"important edocs",
// German (Document (check|check|sign|sent))
"Dokument (überprüfen|prüfen|unterschreiben|geschickt)",
// German (important|urgent|immediate)
"(wichtig|dringend|sofort)"
)
and any(ml.nlu_classifier(.scan.ocr.raw).topics,
.name == "E-Signature"
)
and not strings.count(.scan.ocr.raw, "\n\n\n\n\n\n\n\n\n\n") > 3
)
)
)
)
and not any(file.explode(.),
strings.ilike(.scan.ocr.raw,
"*DocuSigned By*",
"*DocuSign Envelope ID*",
"*Certificate Of Completion*",
"*Adobe Sign*",
// Additional Adobe Acrobat Sign check
"*Powered by\nAdobe\nAcrobat Sign*"
)
or (
.depth == 0
and (
(
.scan.exiftool.page_count > 10
and length(.scan.strings.strings) > 8000
)
or (
.scan.exiftool.producer == "Acrobat Sign"
and any(.scan.exiftool.fields,
.key == "SigningReason"
and .value == "Certified by Adobe Acrobat Sign"
)
)
)
)
// negate resume related messages
or (
any(ml.nlu_classifier(body.current_thread.text).topics,
.name == "Professional and Career Development"
and .confidence == "high"
)
and any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "benign" and .confidence != "low"
)
)
)
)
// accomidate truncated pngs and GIF files which can cause logodetect/OCR failures
or (
any(attachments,
.file_type =~ "gif"
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
or any(beta.parse_exif(.).fields,
.key == "Warning" and .value == "Truncated PNG image"
)
)
and (
any(ml.logo_detect(file.message_screenshot()).brands, .name == "DocuSign")
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
or strings.ilike(beta.ocr(file.message_screenshot()).text, "*DocuSign*")
)
and (
(
any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
.name == "cred_theft" and .confidence != "low"
)
or regex.icontains(beta.ocr(file.message_screenshot()).text,
"((re)?view|access|complete(d)?) document(s)?",
"[^d][^o][^c][^u]sign",
"important edocs",
// German (Document (check|check|sign|sent))
"Dokument (überprüfen|prüfen|unterschreiben|geschickt)",
// German (important|urgent|immediate)
"(wichtig|dringend|sofort)"
)
)
)
and not strings.ilike(beta.ocr(file.message_screenshot()).text,
"*DocuSigned By*",
"*DocuSign Envelope ID*",
"*Certificate Of Completion*",
"*Adobe Sign*"
)
)
)
and (
not profile.by_sender_email().solicited
or profile.by_sender_email().prevalence == "new"
or (
profile.by_sender_email().any_messages_malicious_or_spam
and not profile.by_sender_email().any_messages_benign
)
)
and not profile.by_sender_email().any_messages_benign
// 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 replies to docusign notifications
and not any(headers.references, strings.iends_with(., '@camail.docusign.net'))
Detection logic
Scope: inbound message.
Detects DocuSign phishing messages with no DocuSign links, a DocuSign logo or verbage within an image or PDF attachment, from an untrusted sender.
- inbound message
any of:
all of:
all of:
- length(attachments) > 0
- length(attachments) ≤ 8
- length(filter(attachments, .file_type in $file_types_images)) > 0
all of:
- length(attachments) > 0
all of
attachmentswhere any holds:- .file_type in $file_types_images
- .file_type is 'pdf'
any of:
- .file_extension is 'ics'
- .content_type in ('text/calendar', 'application/ics')
any of:
all of:
- length(body.links) is not 0
any of
body.linkswhere:not:
- .href_url.domain.root_domain matches 'docusign.*'
- length(body.links) is 0
any of:
any of
filter(attachments)where all hold:any of:
any of
ml.logo_detect(.).brandswhere:- .name is 'DocuSign'
any of
file.explode(.)where all hold:- .scan.ocr.raw matches '*DocuSign*'
any of:
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
all of:
.scan.ocr.raw matches any of 5 patterns
((re)?view|access|complete(d)?) document(s)?[^d][^o][^cd][^ue]sign(?:\b|ature)important edocsDokument (überprüfen|prüfen|unterschreiben|geschickt)(wichtig|dringend|sofort)
any of
ml.nlu_classifier(.scan.ocr.raw).topicswhere:- .name is 'E-Signature'
not:
- strings.count(.scan.ocr.raw, '\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n') > 3
not:
any of
file.explode(.)where any holds:.scan.ocr.raw matches any of 5 patterns
*DocuSigned By**DocuSign Envelope ID**Certificate Of Completion**Adobe Sign**Powered by\nAdobe\nAcrobat Sign*
all of:
- .depth is 0
any of:
all of:
- .scan.exiftool.page_count > 10
- length(.scan.strings.strings) > 8000
all of:
- .scan.exiftool.producer is 'Acrobat Sign'
any of
.scan.exiftool.fieldswhere all hold:- .key is 'SigningReason'
- .value is 'Certified by Adobe Acrobat Sign'
all of:
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name is 'Professional and Career Development'
- .confidence is 'high'
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'benign'
- .confidence is not 'low'
all of:
any of
attachmentswhere any holds:- .file_type is 'gif'
any of
beta.parse_exif(.).fieldswhere all hold:- .key is 'Warning'
- .value is 'Truncated PNG image'
any of:
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name is 'DocuSign'
- beta.ocr(file.message_screenshot()).text matches '*DocuSign*'
any of:
any of
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
beta.ocr(file.message_screenshot()).text matches any of 5 patterns
((re)?view|access|complete(d)?) document(s)?[^d][^o][^c][^u]signimportant edocsDokument (überprüfen|prüfen|unterschreiben|geschickt)(wichtig|dringend|sofort)
not:
beta.ocr(file.message_screenshot()).text matches any of 4 patterns
*DocuSigned By**DocuSign Envelope ID**Certificate Of Completion**Adobe Sign*
any of:
not:
- profile.by_sender_email().solicited
- 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
not:
- profile.by_sender_email().any_messages_benign
not:
all of:
any of
headers.hopswhere:any of
.fieldswhere all hold:- .name is 'X-Api-Host'
- .value ends with 'docusign.net'
- sender.display_name contains 'via'
not:
any of
headers.hopswhere:- .received.server.raw matches '.+.docusign.(net|com)'
not:
any of
headers.referenceswhere:- . ends with '@camail.docusign.net'
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].received.server.raw, headers.references, sender.display_name, type.inbound. Sensors: beta.ocr, beta.parse_exif, file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender_email, regex.icontains, regex.imatch, strings.contains, strings.count, strings.ends_with, strings.iends_with, strings.ilike. Reference lists: $file_types_images.
Indicators matched (19)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
attachments[].file_extension | equals | ics |
attachments[].content_type | member | text/calendar |
attachments[].content_type | member | application/ics |
ml.logo_detect(filter(attachments)[]).brands[].name | equals | DocuSign |
strings.ilike | substring | *DocuSign* |
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
regex.icontains | regex | ((re)?view|access|complete(d)?) document(s)? |
regex.icontains | regex | [^d][^o][^cd][^ue]sign(?:\b|ature) |
regex.icontains | regex | important edocs |
regex.icontains | regex | Dokument (überprüfen|prüfen|unterschreiben|geschickt) |
regex.icontains | regex | (wichtig|dringend|sofort) |
7 more
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].name | equals | E-Signature |
attachments[].file_type | equals | gif |
beta.parse_exif(attachments[]).fields[].key | equals | Warning |
beta.parse_exif(attachments[]).fields[].value | equals | Truncated PNG image |
ml.logo_detect(file.message_screenshot()).brands[].name | equals | DocuSign |
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].name | equals | cred_theft |
regex.icontains | regex | [^d][^o][^c][^u]sign |
Stages and Predicates
Stage 1: mql_rule
and
or
any(filter(attachments))
and
not
any(file.explode(filter(attachments)))
or
and
or
and
any(file.explode(filter(attachments)).scan.exiftool.fields)
and
file.explode(filter(attachments)[])[].scan.exiftool.fields[].key eq "SigningReason"
file.explode(filter(attachments)[])[].scan.exiftool.fields[].value eq "Certified by Adobe Acrobat Sign"
file.explode(filter(attachments)[])[].scan.exiftool.producer eq "Acrobat Sign"
and
file.explode(filter(attachments)[])[].scan.exiftool.page_count gt "10"
file.explode(filter(attachments)[])[].scan.strings.strings length_compare "8000"
file.explode(filter(attachments)[])[].depth eq "0"
and
any(ml.nlu_classifier(body.current_thread.text).topics)
and
ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
ml.nlu_classifier(body.current_thread.text).topics.name eq "Professional and Career Development"
any(ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).intents)
and
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].confidence ne "low"
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].name eq "benign"
file.explode(filter(attachments)[])[].scan.ocr.raw match "Adobe Sign"
file.explode(filter(attachments)[])[].scan.ocr.raw match "Certificate Of Completion"
file.explode(filter(attachments)[])[].scan.ocr.raw match "DocuSign Envelope ID"
file.explode(filter(attachments)[])[].scan.ocr.raw match "DocuSigned By"
file.explode(filter(attachments)[])[].scan.ocr.raw match "Powered by\\nAdobe\\nAcrobat Sign"
or
any(file.explode(filter(attachments)))
and
or
and
or
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "((re)?view|access|complete(d)?) document(s)?"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "(wichtig|dringend|sofort)"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "Dokument (überprüfen|prüfen|unterschreiben|geschickt)"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "[^d][^o][^cd][^ue]sign(?:\\b|ature)"
file.explode(filter(attachments)[])[].scan.ocr.raw regex_match "important edocs"
any(ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).topics)
ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).topics.name eq "E-Signature"
not
strings.count func_call "strings.count(file.explode(filter(attachments)[])[].scan.ocr.raw, \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\") > 3"
any(ml.nlu_classifier(file.explode(filter(attachments)).scan.ocr.raw).intents)
and
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].confidence ne "low"
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].name eq "cred_theft"
file.explode(filter(attachments)[])[].scan.ocr.raw match "DocuSign"
any(ml.logo_detect(filter(attachments)).brands)
ml.logo_detect(filter(attachments)).brands.name eq "DocuSign"
and
any(attachments)
or
any(beta.parse_exif(attachments).fields)
and
beta.parse_exif(attachments[]).fields[].key eq "Warning"
beta.parse_exif(attachments[]).fields[].value eq "Truncated PNG image"
attachments.file_type eq "gif"
or
any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents)
and
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.confidence ne "low"
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.name eq "cred_theft"
beta.ocr(file.message_screenshot()).text regex_match "((re)?view|access|complete(d)?) document(s)?"
beta.ocr(file.message_screenshot()).text regex_match "(wichtig|dringend|sofort)"
beta.ocr(file.message_screenshot()).text regex_match "Dokument (überprüfen|prüfen|unterschreiben|geschickt)"
beta.ocr(file.message_screenshot()).text regex_match "[^d][^o][^c][^u]sign"
beta.ocr(file.message_screenshot()).text regex_match "important edocs"
not
or
beta.ocr(file.message_screenshot()).text match "Adobe Sign"
beta.ocr(file.message_screenshot()).text match "Certificate Of Completion"
beta.ocr(file.message_screenshot()).text match "DocuSign Envelope ID"
beta.ocr(file.message_screenshot()).text match "DocuSigned By"
or
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name eq "DocuSign"
beta.ocr(file.message_screenshot()).text match "DocuSign"
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"
or
and
any(body.links)
not
body.links.href_url.domain.root_domain starts_with "docusign."
body.links length_compare "0"
body.links length_compare "0"
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"
profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
or
and
attachments length_compare "0"
attachments length_compare "8"
filter(attachments, .file_type in $file_types_images) length_compare "0"
and
attachments length_compare "0"
macro "all(attachments)"
not
any(headers.hops)
headers.hops.received.server.raw regex_match ".+.docusign.(net|com)"
not
any(headers.references)
headers.references ends_with "@camail.docusign.net"
not
profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
sender.display_name | contains | via | excludes:sender.display_name field:"sender.display_name" value:"via" |
headers.references | array_any | excludes:headers.references |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
beta.ocr(file.message_screenshot()).text | regex_match |
| field:"beta.ocr(file.message_screenshot()).text" kind:regex_match |
beta.ocr(file.message_screenshot()).text | wildcard |
| field:"beta.ocr(file.message_screenshot()).text" kind:wildcard value:"*DocuSign*" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Brand Impersonation: Google (QR Code)
#Detects messages using Google based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(body.current_thread.text) < 1000
and any([subject.subject, sender.display_name, body.current_thread.text],
regex.icontains(.,
'(?:\b2fa\b|\bQ.?R\.?\s?\b|MFA|Muti[ -]?Factor|Auth(?:enticat|e|or|ion)?)'
)
)
and (
any(attachments,
(
.file_type in $file_types_images
or .file_type == "pdf"
or .file_type in~ $file_extensions_macros
)
and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Google"))
)
or any(ml.logo_detect(file.message_screenshot()).brands,
strings.starts_with(.name, "Google")
)
)
and any(attachments,
(
.file_type in $file_types_images
or .file_type == "pdf"
or .file_type in $file_extensions_macros
)
and (
any(file.explode(.),
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
or any(file.explode(.),
.scan.qr.type is not null
and regex.contains(.scan.qr.data, '\.')
)
or (
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
beta.parse_exif(file.message_screenshot()).image_height < 2000
and beta.parse_exif(file.message_screenshot()).image_width < 2000
and any(beta.scan_qr(file.message_screenshot()).items,
.type is not null and regex.contains(.data, '\.')
)
)
)
)
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 (
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.
Detects messages using Google based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
- inbound message
- length(body.current_thread.text) < 1000
any of
[subject.subject, sender.display_name, body.current_thread.text]where:- . matches '(?:\\b2fa\\b|\\bQ.?R\\.?\\s?\\b|MFA|Muti[ -]?Factor|Auth(?:enticat|e|or|ion)?)'
any of:
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
- .file_type in $file_extensions_macros
any of
ml.logo_detect(.).brandswhere:- .name starts with 'Google'
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name starts with 'Google'
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
- .file_type in $file_extensions_macros
any of:
any of
file.explode(.)where all hold:- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
any of
file.explode(.)where all hold:- .scan.qr.type is set
- .scan.qr.data matches '\\.'
all of:
- beta.parse_exif(file.message_screenshot()).image_height < 2000
- beta.parse_exif(file.message_screenshot()).image_width < 2000
any of
beta.scan_qr(file.message_screenshot()).itemswhere all hold:- .type is set
- .data matches '\\.'
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
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, headers.hops, headers.hops[].authentication_results.dmarc, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.parse_exif, beta.scan_qr, file.explode, file.message_screenshot, ml.logo_detect, profile.by_sender, regex.contains, regex.icontains, strings.ilike, strings.starts_with. Reference lists: $file_extensions_macros, $file_types_images, $high_trust_sender_root_domains.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (?:\b2fa\b|\bQ.?R\.?\s?\b|MFA|Muti[ -]?Factor|Auth(?:enticat|e|or|ion)?) |
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | Google |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
regex.contains | regex | \. |
strings.ilike | substring | *fail |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
any(beta.scan_qr(file.message_screenshot()).items)
and
beta.scan_qr(file.message_screenshot()).items.data regex_match "\\."
beta.scan_qr(file.message_screenshot()).items.type is_not_null
beta.parse_exif func_call "beta.parse_exif(file.message_screenshot()).image_height < 2000"
beta.parse_exif func_call "beta.parse_exif(file.message_screenshot()).image_width < 2000"
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.ocr.raw regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.explode(attachments[])[].scan.ocr.raw regex_match "scan|camera"
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.qr.data regex_match "\\."
file.explode(attachments[])[].scan.qr.type is_not_null
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
or
any(attachments)
and
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name starts_with "Google"
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name starts_with "Google"
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"
any([subject.subject, sender.display_name, body.current_thread.text])
[subject.subject, sender.display_name, body.current_thread.text] regex_match "(?:\\b2fa\\b|\\bQ.?R\\.?\\s?\\b|MFA|Muti[ -]?Factor|Auth(?:enticat|e|or|ion)?)"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
body.current_thread.text length_compare "1000"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Brand impersonation: Microsoft (QR code)
#Detects messages using Microsoft image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, PDF, QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
(
.file_type in $file_types_images
or .file_type == "pdf"
or .file_type in~ $file_extensions_macros
)
and (
any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft"))
or any(file.explode(.),
// for Office documents
.flavors.mime == "text/xml"
and any(.scan.strings.strings,
regex.icontains(.,
'Microsoft\s*(?:\w+(?:\s*\w+)?|[[:punct:]]+|\s+){0,3}\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))'
)
)
)
)
)
or any(ml.logo_detect(file.message_screenshot()).brands,
strings.starts_with(.name, "Microsoft")
)
or (
// limited body length
length(body.current_thread.text) < 300
and any(filter(attachments,
.file_type in $file_types_images
// image attachments that are displayed in the body
// when the content-id is corrected, this will be much more simple
and (
any(regex.extract(.content_id, '^<(?P<cid>[^\>]+)\>$'),
strings.icontains(body.html.raw, .named_groups["cid"])
)
or strings.icontains(body.html.raw, .content_id)
)
),
// those images contain the wording
any(file.explode(.),
regex.icontains(.scan.ocr.raw,
'Microsoft\s*(?:\w+(?:\s*\w+)?|[[:punct:]]+|\s+){0,3}\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))'
)
)
)
)
)
and any(attachments,
(
.file_type in $file_types_images
or .file_type == "pdf"
or .file_type in $file_extensions_macros
)
and (
any(file.explode(.),
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
or (
any(file.explode(.),
.scan.qr.type == "url"
// recipient email address is present in the URL, a common tactic used in credential phishing attacks
and any(recipients.to,
(
(strings.icontains(..scan.qr.data, .email.email))
// the recipients sld is in the senders display name
or any(recipients.to,
strings.icontains(sender.display_name,
.email.domain.sld
)
)
// the recipient local is in the body
or any(recipients.to,
strings.icontains(body.current_thread.text,
.email.local_part
)
)
// or the body is null
or body.current_thread.text is null
or body.current_thread.text == ""
// or the subject contains authentication/urgency verbiage
or regex.contains(subject.subject,
"(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
)
)
and (
.email.domain.valid
or strings.icontains(.display_name, "undisclosed")
)
)
)
)
)
)
and (
not sender.email.domain.domain == "microsoft.com"
or not any(headers.hops,
.authentication_results.compauth.verdict is not null
and .authentication_results.compauth.verdict == "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 using Microsoft image based lures, referencing or including a QR code from an Unsolicited sender. These messages often lead users to phishing sites or initiate unwanted downloads.
- inbound message
any of:
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
- .file_type in $file_extensions_macros
any of:
any of
ml.logo_detect(.).brandswhere:- .name starts with 'Microsoft'
any of
file.explode(.)where all hold:- .flavors.mime is 'text/xml'
any of
.scan.strings.stringswhere:- . matches 'Microsoft\\s*(?:\\w+(?:\\s*\\w+)?|[[:punct:]]+|\\s+){0,3}\\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))'
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name starts with 'Microsoft'
all of:
- length(body.current_thread.text) < 300
any of
filter(attachments)where:any of
file.explode(.)where:- .scan.ocr.raw matches 'Microsoft\\s*(?:\\w+(?:\\s*\\w+)?|[[:punct:]]+|\\s+){0,3}\\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))'
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
- .file_type in $file_extensions_macros
any of:
any of
file.explode(.)where all hold:- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
any of
recipients.towhere all hold:any of:
- strings.icontains(.scan.qr.data)
any of
recipients.towhere:- strings.icontains(sender.display_name)
any of
recipients.towhere:- strings.icontains(body.current_thread.text)
- body.current_thread.text is missing
- body.current_thread.text is ''
- subject.subject matches '(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)'
any of:
- .email.domain.valid
- .display_name contains 'undisclosed'
any of:
not:
- sender.email.domain.domain is 'microsoft.com'
not:
any of
headers.hopswhere all hold:- .authentication_results.compauth.verdict is set
- .authentication_results.compauth.verdict is 'pass'
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_id, attachments[].file_type, body.current_thread.text, body.html.raw, headers.hops, headers.hops[].authentication_results.compauth.verdict, 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.display_name, sender.email.domain.domain, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, profile.by_sender, regex.contains, regex.extract, regex.icontains, strings.icontains, strings.starts_with. Reference lists: $file_extensions_macros, $file_types_images.
Indicators matched (11)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | Microsoft |
file.explode(attachments[])[].flavors.mime | equals | text/xml |
regex.icontains | regex | Microsoft\s*(?:\w+(?:\s*\w+)?|[[:punct:]]+|\s+){0,3}\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention)) |
regex.extract | regex | ^<(?P<cid>[^\>]+)\>$ |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
file.explode(attachments[])[].scan.qr.type | equals | url |
body.current_thread.text | equals | |
regex.contains | regex | (Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):) |
strings.icontains | substring | undisclosed |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
any(file.explode(attachments))
and
any(recipients.to)
and
or
any(recipients.to)
strings.icontains func_call "strings.icontains(body.current_thread.text)"
any(recipients.to)
strings.icontains func_call "strings.icontains(sender.display_name)"
body.current_thread.text eq ""
body.current_thread.text is_null
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.data)"
subject.subject regex_match "(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
or
recipients.to.display_name contains "undisclosed"
recipients.to.email.domain.valid eq "true"
file.explode(attachments[])[].scan.qr.type eq "url"
any(file.explode(attachments))
and
file.explode(attachments[])[].scan.ocr.raw regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.explode(attachments[])[].scan.ocr.raw regex_match "scan|camera"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
or
any(attachments)
and
or
any(file.explode(attachments))
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "Microsoft\\s*(?:\\w+(?:\\s*\\w+)?|[[:punct:]]+|\\s+){0,3}\\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))"
file.explode(attachments[])[].flavors.mime eq "text/xml"
any(ml.logo_detect(attachments).brands)
ml.logo_detect(attachments).brands.name starts_with "Microsoft"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_extensions_macros"
macro "attachments[].file_type in file_types_images"
and
any(filter(attachments))
any(file.explode(filter(attachments)))
file.explode(filter(attachments)).scan.ocr.raw regex_match "Microsoft\\s*(?:\\w+(?:\\s*\\w+)?|[[:punct:]]+|\\s+){0,3}\\s*(?:Authenticat(?:e|or|ion)|2fa|Multi.Factor|(?:qr|bar).code|action.require|alert|Att(?:n|ention))"
body.current_thread.text length_compare "300"
any(ml.logo_detect(file.message_screenshot()).brands)
ml.logo_detect(file.message_screenshot()).brands.name starts_with "Microsoft"
or
not
any(headers.hops)
and
headers.hops.authentication_results.compauth.verdict eq "pass"
headers.hops.authentication_results.compauth.verdict is_not_null
not
sender.email.domain.domain eq "microsoft.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"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Credential phishing: Image as content, short or no body contents
#This rule identifies incoming messages with minimal links, all image attachments and either empty, brief or the body text is only a warning banner/disclaimer. It also checks for truncated PNG images or logos in addition to high-confidence credit theft intentions.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Image as content |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(body.links) < 2
and 0 < (length(attachments)) < 3
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) < 900
// or body is most likely all warning banner (text contains the sender and common warning banner language)
and (
(
strings.contains(body.current_thread.text, sender.email.email)
and strings.contains(body.current_thread.text, 'caution')
)
or regex.icontains(body.current_thread.text,
"intended recipient's use only|external email|sent from outside|you don't often"
)
)
)
)
and (
all(attachments,
(.file_type in $file_types_images)
and (
any(file.explode(.),
any(.scan.exiftool.fields, .value == "Truncated PNG image")
or (
any(ml.logo_detect(..).brands, .name is not null)
and any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence == "high"
)
)
)
)
)
)
Detection logic
Scope: inbound message.
This rule identifies incoming messages with minimal links, all image attachments and either empty, brief or the body text is only a warning banner/disclaimer. It also checks for truncated PNG images or logos in addition to high-confidence credit theft intentions.
- inbound message
- length(body.links) < 2
all of:
- length(attachments) > 0
- length(attachments) < 3
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) < 900
any of:
all of:
- strings.contains(body.current_thread.text)
- body.current_thread.text contains 'caution'
- body.current_thread.text matches "intended recipient's use only|external email|sent from outside|you don't often"
all of
attachmentswhere all hold:- .file_type in $file_types_images
any of
file.explode(.)where any holds:any of
.scan.exiftool.fieldswhere:- .value is 'Truncated PNG image'
all of:
any of
ml.logo_detect(.).brandswhere:- .name is set
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
Inspects: attachments[].file_type, body.current_thread.text, body.links, sender.email.email, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.contains. Reference lists: $file_types_images.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | caution |
regex.icontains | regex | intended recipient's use only|external email|sent from outside|you don't often |
file.explode(attachments[])[].scan.exiftool.fields[].value | equals | Truncated PNG image |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
or
and
or
and
body.current_thread.text contains "caution"
strings.contains func_call "strings.contains(body.current_thread.text)"
body.current_thread.text regex_match "intended recipient's use only|external email|sent from outside|you don't often"
body.current_thread.text length_compare "900"
and
body.current_thread.text length_compare "0"
body.current_thread.text length_compare "10"
body.current_thread.text is_null
attachments length_compare "0"
attachments length_compare "3"
body.links length_compare "2"
type.inbound eq "true"
macro "all(attachments)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains value:"caution" |
body.current_thread.text | is_null | field:"body.current_thread.text" kind:is_null | |
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
EML attachment with credential theft language (unknown sender)
#Identifies EML attachments that use credential theft language from unknown senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// we don't look for links because it could be a QR code
and any(attachments,
(.content_type == "message/rfc822" or .file_extension =~ "eml")
and (
// credential theft language in the attached EML
any(ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intents,
.name == "cred_theft" and .confidence == "high"
)
// credential theft language in an attachment in the attached EML
or any(file.parse_eml(.).attachments,
any(ml.nlu_classifier(beta.ocr(.).text).intents,
.name == "cred_theft" and .confidence == "high"
)
)
)
and not strings.like(file.parse_eml(.).sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
// some systems attach the bounceback this way
and not any(file.parse_eml(.).attachments,
.content_type in (
"message/delivery-status",
"message/feedback-report"
)
)
// negate Microsoft Dynamic Delivery
and not (
length(file.parse_eml(.).attachments) == 0
and strings.icontains(file.parse_eml(.).body.current_thread.text,
"Your attachments are currently being scanned by Safe Attachments"
)
)
// Mimecast Protection attached EMLs when replacing attachments
and not (
(
strings.iends_with(.file_name, 'was removed from this message')
or .file_name == "We found suspicious links"
or .file_name == 'We sent you safe versions of your files'
)
and length(file.parse_eml(.).headers.hops) == 1
and any(file.parse_eml(.).headers.hops[0].fields,
.name == "X-MC-System"
)
and any(file.parse_eml(.).headers.hops[0].fields,
.name == "Content-Type"
and strings.contains(.value, '; boundary="MCBoundary=_')
)
)
)
// exclude bounce backs & read receipts
and not strings.like(sender.email.local_part,
"*postmaster*",
"*mailer-daemon*",
"*administrator*"
)
and not regex.icontains(subject.subject, "^(undelivered|undeliverable|read:)")
and not any(attachments,
.content_type in (
"message/delivery-status",
"message/feedback-report"
)
)
// 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_email().solicited
or (
profile.by_sender_email().any_messages_malicious_or_spam
and not profile.by_sender_email().any_messages_benign
)
// sender address listed as a recipient
or (
length(recipients.to) == 1
and sender.email.email in map(recipients.to, .email.email)
)
)
and not profile.by_sender_email().any_messages_benign
// 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.
Identifies EML attachments that use credential theft language from unknown senders.
- inbound message
any of
attachmentswhere all hold:any of:
- .content_type is 'message/rfc822'
- .file_extension is 'eml'
any of:
any of
ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
any of
file.parse_eml(.).attachmentswhere:any of
ml.nlu_classifier(beta.ocr(.).text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
not:
file.parse_eml(.).sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
any of
file.parse_eml(.).attachmentswhere:- .content_type in ('message/delivery-status', 'message/feedback-report')
not:
all of:
- length(file.parse_eml(.).attachments) is 0
- file.parse_eml(.).body.current_thread.text contains 'Your attachments are currently being scanned by Safe Attachments'
not:
all of:
any of:
- .file_name ends with 'was removed from this message'
- .file_name is 'We found suspicious links'
- .file_name is 'We sent you safe versions of your files'
- length(file.parse_eml(.).headers.hops) is 1
any of
file.parse_eml(.).headers.hops[0].fieldswhere:- .name is 'X-MC-System'
any of
file.parse_eml(.).headers.hops[0].fieldswhere all hold:- .name is 'Content-Type'
- .value contains '; boundary="MCBoundary=_'
not:
sender.email.local_part matches any of 3 patterns
*postmaster**mailer-daemon**administrator*
not:
- subject.subject matches '^(undelivered|undeliverable|read:)'
not:
any of
attachmentswhere:- .content_type in ('message/delivery-status', 'message/feedback-report')
not:
any of
headers.referenceswhere:- strings.contains(body.html.display_text)
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
all of:
- length(recipients.to) is 1
- sender.email.email in map(recipients.to, .email.email)
not:
- profile.by_sender_email().any_messages_benign
not:
all of:
- sender.email.email is 'analyzer@analyzer.securityeducation.com'
any of
headers.domainswhere:- .root_domain is 'pphosted.com'
- headers.auth_summary.spf.pass
- headers.auth_summary.dmarc.pass
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_name, body.html.display_text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.references, recipients.to, recipients.to[].email.email, sender.email.email, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ocr, file.parse_eml, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.contains, strings.icontains, strings.iends_with, strings.like.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | equals | eml |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].confidence | equals | high |
ml.nlu_classifier(beta.ocr(file.parse_eml(attachments[]).attachments[]).text).intents[].name | equals | cred_theft |
ml.nlu_classifier(beta.ocr(file.parse_eml(attachments[]).attachments[]).text).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
not
and
any(file.parse_eml(attachments).headers.hops[0].fields)
and
file.parse_eml(attachments[]).headers.hops[0].fields[].name eq "Content-Type"
file.parse_eml(attachments[]).headers.hops[0].fields[].value contains "; boundary=\"MCBoundary=_"
or
attachments.file_name ends_with "was removed from this message"
attachments.file_name eq "We found suspicious links"
attachments.file_name eq "We sent you safe versions of your files"
any(file.parse_eml(attachments).headers.hops[0].fields)
file.parse_eml(attachments).headers.hops[0].fields.name eq "X-MC-System"
file.parse_eml(attachments[]).headers.hops length_compare "1"
or
any(file.parse_eml(attachments).attachments)
any(ml.nlu_classifier(beta.ocr(file.parse_eml(attachments).attachments).text).intents)
and
ml.nlu_classifier(beta.ocr(file.parse_eml(attachments[]).attachments[]).text).intents[].confidence eq "high"
ml.nlu_classifier(beta.ocr(file.parse_eml(attachments[]).attachments[]).text).intents[].name eq "cred_theft"
any(ml.nlu_classifier(file.parse_eml(attachments).body.current_thread.text).intents)
and
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].confidence eq "high"
ml.nlu_classifier(file.parse_eml(attachments[]).body.current_thread.text).intents[].name eq "cred_theft"
not
any(file.parse_eml(attachments).attachments)
file.parse_eml(attachments).attachments.content_type in ["message/delivery-status", "message/feedback-report"]
not
and
file.parse_eml(attachments[]).attachments length_compare "0"
file.parse_eml(attachments[]).body.current_thread.text contains "Your attachments are currently being scanned by Safe Attachments"
not
or
file.parse_eml(attachments[]).sender.email.local_part match "administrator"
file.parse_eml(attachments[]).sender.email.local_part match "mailer-daemon"
file.parse_eml(attachments[]).sender.email.local_part match "postmaster"
or
attachments.content_type eq "message/rfc822"
attachments.file_extension eq "eml"
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"
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"
and
recipients.to length_compare "1"
macro "sender.email.email in map(recipients.to, .email.email)"
not
any(attachments)
attachments.content_type in ["message/delivery-status", "message/feedback-report"]
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_email func_call "profile.by_sender_email().any_messages_benign"
not
subject.subject regex_match "^(undelivered|undeliverable|read:)"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Encrypted Microsoft Office files from untrusted sender
#Detects encrypted Microsoft Office document attachments (Word, Excel, PowerPoint, Access) from untrusted senders or high-trust senders failing DMARC authentication, which may indicate an effort to bypass security scanning.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Callback Phishing, Credential Phishing, Extortion, Malware/Ransomware, Spam |
| Tactics and techniques | Encryption, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
// Word documents
strings.iends_with(.file_name, ".doc")
or strings.iends_with(.file_name, ".docx")
or strings.iends_with(.file_name, ".docm")
or .content_type == "application/msword"
or .content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
or .file_type in ("doc", "docx")
or
// Excel documents
strings.iends_with(.file_name, ".xls")
or strings.iends_with(.file_name, ".xlsx")
or strings.iends_with(.file_name, ".xlsm")
or .content_type == "application/vnd.ms-excel"
or .content_type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
or .file_type in ("xls", "xlsx")
or
// PowerPoint documents
strings.iends_with(.file_name, ".ppt")
or strings.iends_with(.file_name, ".pptx")
or strings.iends_with(.file_name, ".pptm")
or .content_type == "application/vnd.ms-powerpoint"
or .content_type == "application/vnd.openxmlformats-officedocument.presentationml.presentation"
or .file_type in ("ppt", "pptx")
or
// Access documents
strings.iends_with(.file_name, ".accdb")
or strings.iends_with(.file_name, ".mdb")
or .content_type == "application/msaccess"
or .content_type == "application/x-msaccess"
or .content_type == "application/vnd.ms-access"
)
and any(file.explode(.),
any(.scan.yara.matches, .name == 'aes_encryption_keywords')
)
)
// Negating high-trust 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.
Detects encrypted Microsoft Office document attachments (Word, Excel, PowerPoint, Access) from untrusted senders or high-trust senders failing DMARC authentication, which may indicate an effort to bypass security scanning.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_name ends with '.doc'
- .file_name ends with '.docx'
- .file_name ends with '.docm'
- .content_type is 'application/msword'
- .content_type is 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- .file_type in ('doc', 'docx')
- .file_name ends with '.xls'
- .file_name ends with '.xlsx'
- .file_name ends with '.xlsm'
- .content_type is 'application/vnd.ms-excel'
- .content_type is 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
- .file_type in ('xls', 'xlsx')
- .file_name ends with '.ppt'
- .file_name ends with '.pptx'
- .file_name ends with '.pptm'
- .content_type is 'application/vnd.ms-powerpoint'
- .content_type is 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
- .file_type in ('ppt', 'pptx')
- .file_name ends with '.accdb'
- .file_name ends with '.mdb'
- .content_type is 'application/msaccess'
- .content_type is 'application/x-msaccess'
- .content_type is 'application/vnd.ms-access'
any of
file.explode(.)where:any of
.scan.yara.matcheswhere:- .name is 'aes_encryption_keywords'
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[].content_type, attachments[].file_name, attachments[].file_type, headers.hops, headers.hops[].authentication_results.dmarc, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, strings.iends_with, strings.ilike. Reference lists: $high_trust_sender_root_domains.
Indicators matched (28)
| Field | Match | Value |
|---|---|---|
strings.iends_with | suffix | .doc |
strings.iends_with | suffix | .docx |
strings.iends_with | suffix | .docm |
attachments[].content_type | equals | application/msword |
attachments[].content_type | equals | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
strings.iends_with | suffix | .xls |
strings.iends_with | suffix | .xlsx |
strings.iends_with | suffix | .xlsm |
attachments[].content_type | equals | application/vnd.ms-excel |
attachments[].content_type | equals | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
16 more
attachments[].file_type | member | xls |
attachments[].file_type | member | xlsx |
strings.iends_with | suffix | .ppt |
strings.iends_with | suffix | .pptx |
strings.iends_with | suffix | .pptm |
attachments[].content_type | equals | application/vnd.ms-powerpoint |
attachments[].content_type | equals | application/vnd.openxmlformats-officedocument.presentationml.presentation |
attachments[].file_type | member | ppt |
attachments[].file_type | member | pptx |
strings.iends_with | suffix | .accdb |
strings.iends_with | suffix | .mdb |
attachments[].content_type | equals | application/msaccess |
attachments[].content_type | equals | application/x-msaccess |
attachments[].content_type | equals | application/vnd.ms-access |
file.explode(attachments[])[].scan.yara.matches[].name | equals | aes_encryption_keywords |
strings.ilike | substring | *fail |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.yara.matches)
file.explode(attachments).scan.yara.matches.name eq "aes_encryption_keywords"
or
attachments.content_type eq "application/msaccess"
attachments.content_type eq "application/msword"
attachments.content_type eq "application/vnd.ms-access"
attachments.content_type eq "application/vnd.ms-excel"
attachments.content_type eq "application/vnd.ms-powerpoint"
attachments.content_type eq "application/vnd.openxmlformats-officedocument.presentationml.presentation"
attachments.content_type eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
attachments.content_type eq "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
attachments.content_type eq "application/x-msaccess"
attachments.file_name ends_with ".accdb"
attachments.file_name ends_with ".doc"
attachments.file_name ends_with ".docm"
attachments.file_name ends_with ".docx"
attachments.file_name ends_with ".mdb"
attachments.file_name ends_with ".ppt"
attachments.file_name ends_with ".pptm"
attachments.file_name ends_with ".pptx"
attachments.file_name ends_with ".xls"
attachments.file_name ends_with ".xlsm"
attachments.file_name ends_with ".xlsx"
attachments.file_type in ["doc", "docx"]
attachments.file_type in ["ppt", "pptx"]
attachments.file_type in ["xls", "xlsx"]
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"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Extortion / Sextortion - PDF attachment leveraging breach data from freemail sender
#Detects sextortion attempts leveraging breach data, including names, addresses, phone numbers and frequently using Google Maps/Bing Maps streetview images to bolster confidence and fear.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Free email provider, PDF, Social engineering, QR code |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// sender is a freemail domain
and sender.email.domain.root_domain in $free_email_providers
// attachment filename is the same as the subject
and any(attachments,
(
strings.ilevenshtein(strings.concat(subject.subject,
".",
.file_extension
),
.file_name
) <= 1
)
or strings.contains(.file_name, subject.subject)
)
// body contains a US address, or the body is the subject
and (
regex.icontains(body.current_thread.text,
'\d+\s[\w\s.]+(?:\n)?[\w\s]+\s[A-Z]{2}\s\d{5}(?:-\d{4})?(?:\n)?|\d+\s[\w\s.]+(?:Street|St|Avenue|Ave|Boulevard|Blvd|Road|Rd|Drive|Dr|Lane|Ln|Court|Ct|Way|Place|Pl|Terrace|Ter|Circle|Cir|Parkway|Pkwy|Trail|Trl|Highway|Hwy|Loop)\b\.?',
// a Canadian address
'\d+\s[\w\s.]+(?:\n)?[\w\s]+\s((?:Ontario|ON)|(?:Quebec|QC)|(?:Nova Scotia|NS)|(?:New Brunswick|NB)|(?:Manitoba|MB)|(?:British Columbia|BC)|(?:Prince Edward Island|PEI?)|(?:Saskatchewan|SK)|(?:Alberta|AB)|(?:Newfoundland and Labrador|NL)|(?:Yukon|YT)|(?:Northwest Territories|NT)|(?:Nunavut|NU))\s*[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d'
)
or subject.subject == body.current_thread.text
)
// there's a PDF attachment with an image at a depth of one, measuring 148x148 and containing a QR code that is a BTC address
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
(
(.depth == 1 and .flavors.mime == "image/jpeg")
and (
.scan.exiftool.image_height == 148
and .scan.exiftool.image_width == 148
and regex.match(.scan.qr.data,
'(1[a-km-zA-HJ-NP-Z1-9]{25,34}|3[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qp-z0-9]{39,59})'
)
)
)
or (
any(.scan.strings.strings,
regex.icontains(.,
'Amount(?:\s*\w+){0,3}\s*:?\s*(?:USD\s*)?(?:\$\s?\d+|\d+\s?\$?)'
)
)
and any(.scan.strings.strings,
regex.icontains(.,
'(\bBITCOIN\b|\bBTC\b|\bLTC\b|Wallet)'
)
)
)
)
)
Detection logic
Scope: inbound message.
Detects sextortion attempts leveraging breach data, including names, addresses, phone numbers and frequently using Google Maps/Bing Maps streetview images to bolster confidence and fear.
- inbound message
- sender.email.domain.root_domain in $free_email_providers
any of
attachmentswhere any holds:- strings.ilevenshtein(strings.concat(subject.subject, '.', .file_extension)) ≤ 1
- strings.contains(.file_name)
any of:
body.current_thread.text matches any of 2 patterns
\d+\s[\w\s.]+(?:\n)?[\w\s]+\s[A-Z]{2}\s\d{5}(?:-\d{4})?(?:\n)?|\d+\s[\w\s.]+(?:Street|St|Avenue|Ave|Boulevard|Blvd|Road|Rd|Drive|Dr|Lane|Ln|Court|Ct|Way|Place|Pl|Terrace|Ter|Circle|Cir|Parkway|Pkwy|Trail|Trl|Highway|Hwy|Loop)\b\.?\d+\s[\w\s.]+(?:\n)?[\w\s]+\s((?:Ontario|ON)|(?:Quebec|QC)|(?:Nova Scotia|NS)|(?:New Brunswick|NB)|(?:Manitoba|MB)|(?:British Columbia|BC)|(?:Prince Edward Island|PEI?)|(?:Saskatchewan|SK)|(?:Alberta|AB)|(?:Newfoundland and Labrador|NL)|(?:Yukon|YT)|(?:Northwest Territories|NT)|(?:Nunavut|NU))\s*[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d
- subject.subject is body.current_thread.text
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where any holds:all of:
all of:
- .depth is 1
- .flavors.mime is 'image/jpeg'
all of:
- .scan.exiftool.image_height is 148
- .scan.exiftool.image_width is 148
- .scan.qr.data matches '(1[a-km-zA-HJ-NP-Z1-9]{25,34}|3[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qp-z0-9]{39,59})'
all of:
any of
.scan.strings.stringswhere:- . matches 'Amount(?:\\s*\\w+){0,3}\\s*:?\\s*(?:USD\\s*)?(?:\\$\\s?\\d+|\\d+\\s?\\$?)'
any of
.scan.strings.stringswhere:- . matches '(\\bBITCOIN\\b|\\bBTC\\b|\\bLTC\\b|Wallet)'
Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, regex.icontains, regex.match, strings.concat, strings.contains, strings.ilevenshtein. Reference lists: $free_email_providers.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | \d+\s[\w\s.]+(?:\n)?[\w\s]+\s[A-Z]{2}\s\d{5}(?:-\d{4})?(?:\n)?|\d+\s[\w\s.]+(?:Street|St|Avenue|Ave|Boulevard|Blvd|Road|Rd|Drive|Dr|Lane|Ln|Court|Ct|Way|Place|Pl|Terrace|Ter|Circle|Cir|Parkway|Pkwy|Trail|Trl|Highway|Hwy|Loop)\b\.? |
regex.icontains | regex | \d+\s[\w\s.]+(?:\n)?[\w\s]+\s((?:Ontario|ON)|(?:Quebec|QC)|(?:Nova Scotia|NS)|(?:New Brunswick|NB)|(?:Manitoba|MB)|(?:British Columbia|BC)|(?:Prince Edward Island|PEI?)|(?:Saskatchewan|SK)|(?:Alberta|AB)|(?:Newfoundland and Labrador|NL)|(?:Yukon|YT)|(?:Northwest Territories|NT)|(?:Nunavut|NU))\s*[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d |
attachments[].file_type | equals | pdf |
file.explode(attachments[])[].flavors.mime | equals | image/jpeg |
regex.match | regex | (1[a-km-zA-HJ-NP-Z1-9]{25,34}|3[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qp-z0-9]{39,59}) |
regex.icontains | regex | Amount(?:\s*\w+){0,3}\s*:?\s*(?:USD\s*)?(?:\$\s?\d+|\d+\s?\$?) |
regex.icontains | regex | (\bBITCOIN\b|\bBTC\b|\bLTC\b|Wallet) |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
or
and
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "(\\bBITCOIN\\b|\\bBTC\\b|\\bLTC\\b|Wallet)"
any(file.explode(attachments).scan.strings.strings)
file.explode(attachments).scan.strings.strings regex_match "Amount(?:\\s*\\w+){0,3}\\s*:?\\s*(?:USD\\s*)?(?:\\$\\s?\\d+|\\d+\\s?\\$?)"
and
file.explode(attachments[])[].depth eq "1"
file.explode(attachments[])[].flavors.mime eq "image/jpeg"
file.explode(attachments[])[].scan.exiftool.image_height eq "148"
file.explode(attachments[])[].scan.exiftool.image_width eq "148"
file.explode(attachments[])[].scan.qr.data regex_match "(1[a-km-zA-HJ-NP-Z1-9]{25,34}|3[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qp-z0-9]{39,59})"
attachments.file_type eq "pdf"
any(attachments)
or
strings.contains func_call "strings.contains(attachments[].file_name)"
strings.ilevenshtein func_call "strings.ilevenshtein(strings.concat(subject.subject, '.', attachments[].file_extension)) <= 1"
or
body.current_thread.text regex_match "\\d+\\s[\\w\\s.]+(?:\\n)?[\\w\\s]+\\s((?:Ontario|ON)|(?:Quebec|QC)|(?:Nova Scotia|NS)|(?:New Brunswick|NB)|(?:Manitoba|MB)|(?:British Columbia|BC)|(?:Prince Edward Island|PEI?)|(?:Saskatchewan|SK)|(?:Alberta|AB)|(?:Newfoundland and Labrador|NL)|(?:Yukon|YT)|(?:Northwest Territories|NT)|(?:Nunavut|NU))\\s*[ABCEGHJ-NPRSTVXY]\\d[ABCEGHJ-NPRSTV-Z][ -]?\\d[ABCEGHJ-NPRSTV-Z]\\d"
body.current_thread.text regex_match "\\d+\\s[\\w\\s.]+(?:\\n)?[\\w\\s]+\\s[A-Z]{2}\\s\\d{5}(?:-\\d{4})?(?:\\n)?|\\d+\\s[\\w\\s.]+(?:Street|St|Avenue|Ave|Boulevard|Blvd|Road|Rd|Drive|Dr|Lane|Ln|Court|Ct|Way|Place|Pl|Terrace|Ter|Circle|Cir|Parkway|Pkwy|Trail|Trl|Highway|Hwy|Loop)\\b\\.?"
subject.subject cross_field_compare "body.current_thread.text"
type.inbound eq "true"
macro "sender.email.domain.root_domain in free_email_providers"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | regex_match |
| field:"body.current_thread.text" kind:regex_match |
subject.subject | cross_field_compare |
| field:"subject.subject" kind:cross_field_compare value:"body.current_thread.text" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Extortion / sextortion in attachment from untrusted sender
#Detects extortion and sextortion attempts by analyzing attachment text from an untrusted sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Extortion |
| Tactics and techniques | Social engineering, Spoofing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(attachments) < 2
and (
length(body.current_thread.text) < 500
or (
length(ml.nlu_classifier(body.current_thread.text).intents) > 0
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name != "benign"
)
)
or regex.icontains(body.html.raw, '<img[^>]+src="cid:')
)
and any(attachments,
// use ocr output from file.explode on pdfs/images
(
(.file_type in $file_types_images or .file_type == "pdf")
and any(filter(file.explode(.), .scan.ocr.raw is not null),
(
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "extortion" and .confidence == "high"
)
and any(ml.nlu_classifier(.scan.ocr.raw).entities,
.name == "financial"
)
)
or 3 of (
// malware terms
regex.icontains(.scan.ocr.raw,
"((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))"
),
// actions recorded
regex.icontains(.scan.ocr.raw,
"porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off"
),
regex.icontains(.scan.ocr.raw,
"pervert|perversion|masturbat"
),
// a timeframe to pay
regex.icontains(.scan.ocr.raw,
'\d\d hours',
'(?:one|two|three) days?'
),
// a promise from the actor
regex.icontains(.scan.ocr.raw,
'permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?)'
),
// a threat from the actor
regex.icontains(.scan.ocr.raw,
'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*.{0,10}(contacts|media|family|friends)'
),
// bitcoin
(
regex.icontains(.scan.ocr.raw,
'bitcoin|\bbtc\b|blockchain'
)
// negate cryptocurrency newsletters
and not (
any(body.links,
strings.icontains(.display_text, "unsubscribe")
and (
strings.icontains(.href_url.path, "unsubscribe")
// handle mimecast URL rewrites
or (
.href_url.domain.root_domain == 'mimecastprotect.com'
and strings.icontains(.href_url.query_params,
sender.email.domain.root_domain
)
)
)
)
)
),
// bitcoin wallet address + threat
(
strings.icontains(.scan.ocr.raw, "contact the police")
and regex.icontains(.scan.ocr.raw,
'(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b'
)
),
regex.icontains(.scan.ocr.raw, 'bc1q.{0,50}\b')
)
)
)
or
// use file.parse_text on plain text files
(
(
.file_extension in ("txt")
and (
(
any(ml.nlu_classifier(file.parse_text(.).text).intents,
.name == "extortion" and .confidence == "high"
)
and any(ml.nlu_classifier(file.parse_text(.).text).entities,
.name == "financial"
)
)
or 3 of (
// malware terms
regex.icontains(file.parse_text(.).text,
"((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))"
),
// actions recorded
regex.icontains(file.parse_text(.).text,
"porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off"
),
regex.icontains(file.parse_text(.).text,
"pervert|perversion|masturbat"
),
// a timeframe to pay
regex.icontains(file.parse_text(.).text,
'\d\d hours',
'(?:one|two|three) days?'
),
// a promise from the actor
regex.icontains(file.parse_text(.).text,
'permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?)'
),
// a threat from the actor
regex.icontains(file.parse_text(.).text,
'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*.{0,10}(contacts|media|family|friends)'
),
// bitcoin
(
regex.icontains(file.parse_text(.).text,
'bitcoin|\bbtc\b|blockchain'
)
// negate cryptocurrency newsletters
and not (
any(body.links,
strings.icontains(.display_text, "unsubscribe")
and (
strings.icontains(.href_url.path, "unsubscribe")
// handle mimecast URL rewrites
or (
.href_url.domain.root_domain == 'mimecastprotect.com'
and strings.icontains(.href_url.query_params,
sender.email.domain.root_domain
)
)
)
)
)
),
// bitcoin wallet address + threat
(
strings.icontains(file.parse_text(.).text,
"contact the police"
)
and regex.icontains(file.parse_text(.).text,
'(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b'
)
),
regex.icontains(file.parse_text(.).text, 'bc1q.{0,50}\b')
)
)
)
)
)
and (
not profile.by_sender().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
or any(headers.hops, any(.fields, .name == "X-Google-Group-Id"))
// many extortion emails spoof sender domains and fail sender authentication
or any(headers.hops,
.authentication_results.dmarc == "fail"
or .authentication_results.compauth.verdict not in ("pass", "softpass")
)
)
Detection logic
Scope: inbound message.
Detects extortion and sextortion attempts by analyzing attachment text from an untrusted sender.
- inbound message
- length(attachments) < 2
any of:
- length(body.current_thread.text) < 500
all of:
- length(ml.nlu_classifier(body.current_thread.text).intents) > 0
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name is not 'benign'
- body.html.raw matches '<img[^>]+src="cid:'
any of
attachmentswhere any holds:all of:
any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
any of
filter(...)where any holds:all of:
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'extortion'
- .confidence is 'high'
any of
ml.nlu_classifier(.scan.ocr.raw).entitieswhere:- .name is 'financial'
at least 3 of:
- .scan.ocr.raw matches '((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))'
- .scan.ocr.raw matches 'porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off'
- .scan.ocr.raw matches 'pervert|perversion|masturbat'
.scan.ocr.raw matches any of 2 patterns
\d\d hours(?:one|two|three) days?
- .scan.ocr.raw matches 'permanently delete|destroy (?:\\w+\\s*){0,4} (?:data|evidence|videos?)'
- .scan.ocr.raw matches 'sen[dt]\\s*(?:\\w+\\s*){0,2}\\s*to\\s*(?:\\w+\\s*){0,3}\\s*.{0,10}(contacts|media|family|friends)'
all of:
- .scan.ocr.raw matches 'bitcoin|\\bbtc\\b|blockchain'
not:
any of
body.linkswhere all hold:- .display_text contains 'unsubscribe'
any of:
- .href_url.path contains 'unsubscribe'
all of:
- .href_url.domain.root_domain is 'mimecastprotect.com'
- strings.icontains(.href_url.query_params)
all of:
- .scan.ocr.raw contains 'contact the police'
- .scan.ocr.raw matches '(\\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\\b)|\\bX[1-9A-HJ-NP-Za-km-z]{33}\\b|\\b(0x[a-fA-F0-9]{40})\\b|\\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\\b|\\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\\b'
- .scan.ocr.raw matches 'bc1q.{0,50}\\b'
all of:
- .file_extension in ('txt')
any of:
all of:
any of
ml.nlu_classifier(file.parse_text(.).text).intentswhere all hold:- .name is 'extortion'
- .confidence is 'high'
any of
ml.nlu_classifier(file.parse_text(.).text).entitieswhere:- .name is 'financial'
at least 3 of:
- file.parse_text(.).text matches '((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))'
- file.parse_text(.).text matches 'porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off'
- file.parse_text(.).text matches 'pervert|perversion|masturbat'
file.parse_text(.).text matches any of 2 patterns
\d\d hours(?:one|two|three) days?
- file.parse_text(.).text matches 'permanently delete|destroy (?:\\w+\\s*){0,4} (?:data|evidence|videos?)'
- file.parse_text(.).text matches 'sen[dt]\\s*(?:\\w+\\s*){0,2}\\s*to\\s*(?:\\w+\\s*){0,3}\\s*.{0,10}(contacts|media|family|friends)'
all of:
- file.parse_text(.).text matches 'bitcoin|\\bbtc\\b|blockchain'
not:
any of
body.linkswhere all hold:- .display_text contains 'unsubscribe'
any of:
- .href_url.path contains 'unsubscribe'
all of:
- .href_url.domain.root_domain is 'mimecastprotect.com'
- strings.icontains(.href_url.query_params)
all of:
- file.parse_text(.).text contains 'contact the police'
- file.parse_text(.).text matches '(\\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\\b)|\\bX[1-9A-HJ-NP-Za-km-z]{33}\\b|\\b(0x[a-fA-F0-9]{40})\\b|\\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\\b|\\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\\b'
- file.parse_text(.).text matches 'bc1q.{0,50}\\b'
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
any of
headers.hopswhere:any of
.fieldswhere:- .name is 'X-Google-Group-Id'
any of
headers.hopswhere any holds:- .authentication_results.dmarc is 'fail'
- .authentication_results.compauth.verdict not in ('pass', 'softpass')
Inspects: attachments[].file_extension, attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, headers.hops, headers.hops[].authentication_results.compauth.verdict, headers.hops[].authentication_results.dmarc, headers.hops[].fields, headers.hops[].fields[].name, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, file.parse_text, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains. Reference lists: $file_types_images.
Indicators matched (22)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | <img[^>]+src="cid: |
attachments[].file_type | equals | pdf |
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].name | equals | extortion |
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].confidence | equals | high |
ml.nlu_classifier(filter(...)[].scan.ocr.raw).entities[].name | equals | financial |
regex.icontains | regex | ((spy|mal)ware|trojan|remote control|infiltrat(ed|ion)) |
regex.icontains | regex | porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off |
regex.icontains | regex | pervert|perversion|masturbat |
regex.icontains | regex | \d\d hours |
regex.icontains | regex | (?:one|two|three) days? |
regex.icontains | regex | permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?) |
regex.icontains | regex | sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*.{0,10}(contacts|media|family|friends) |
10 more
regex.icontains | regex | bitcoin|\bbtc\b|blockchain |
strings.icontains | substring | contact the police |
regex.icontains | regex | (\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b |
regex.icontains | regex | bc1q.{0,50}\b |
attachments[].file_extension | member | txt |
ml.nlu_classifier(file.parse_text(attachments[]).text).intents[].name | equals | extortion |
ml.nlu_classifier(file.parse_text(attachments[]).text).intents[].confidence | equals | high |
ml.nlu_classifier(file.parse_text(attachments[]).text).entities[].name | equals | financial |
headers.hops[].fields[].name | equals | X-Google-Group-Id |
headers.hops[].authentication_results.dmarc | equals | fail |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
or
and
any(filter(...))
or
and
not
any(body.links)
and
or
and
body.links.href_url.domain.root_domain eq "mimecastprotect.com"
strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
body.links.href_url.path contains "unsubscribe"
body.links.display_text contains "unsubscribe"
filter(...).scan.ocr.raw regex_match "bitcoin|\\bbtc\\b|blockchain"
and
any(ml.nlu_classifier(filter(...).scan.ocr.raw).intents)
and
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].confidence eq "high"
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].name eq "extortion"
any(ml.nlu_classifier(filter(...).scan.ocr.raw).entities)
ml.nlu_classifier(filter(...).scan.ocr.raw).entities.name eq "financial"
and
filter(...).scan.ocr.raw contains "contact the police"
filter(...).scan.ocr.raw regex_match "(\\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\\b)|\\bX[1-9A-HJ-NP-Za-km-z]{33}\\b|\\b(0x[a-fA-F0-9]{40})\\b|\\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\\b|\\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\\b"
filter(...).scan.ocr.raw regex_match "((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))"
filter(...).scan.ocr.raw regex_match "(?:one|two|three) days?"
filter(...).scan.ocr.raw regex_match "\\d\\d hours"
filter(...).scan.ocr.raw regex_match "bc1q.{0,50}\\b"
filter(...).scan.ocr.raw regex_match "permanently delete|destroy (?:\\w+\\s*){0,4} (?:data|evidence|videos?)"
filter(...).scan.ocr.raw regex_match "pervert|perversion|masturbat"
filter(...).scan.ocr.raw regex_match "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off"
filter(...).scan.ocr.raw regex_match "sen[dt]\\s*(?:\\w+\\s*){0,2}\\s*to\\s*(?:\\w+\\s*){0,3}\\s*.{0,10}(contacts|media|family|friends)"
or
attachments.file_type eq "pdf"
macro "attachments[].file_type in file_types_images"
and
or
and
not
any(body.links)
and
or
and
body.links.href_url.domain.root_domain eq "mimecastprotect.com"
strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
body.links.href_url.path contains "unsubscribe"
body.links.display_text contains "unsubscribe"
file.parse_text(attachments[]).text regex_match "bitcoin|\\bbtc\\b|blockchain"
and
any(ml.nlu_classifier(file.parse_text(attachments).text).intents)
and
ml.nlu_classifier(file.parse_text(attachments[]).text).intents[].confidence eq "high"
ml.nlu_classifier(file.parse_text(attachments[]).text).intents[].name eq "extortion"
any(ml.nlu_classifier(file.parse_text(attachments).text).entities)
ml.nlu_classifier(file.parse_text(attachments).text).entities.name eq "financial"
and
file.parse_text(attachments[]).text contains "contact the police"
file.parse_text(attachments[]).text regex_match "(\\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\\b)|\\bX[1-9A-HJ-NP-Za-km-z]{33}\\b|\\b(0x[a-fA-F0-9]{40})\\b|\\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\\b|\\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\\b"
file.parse_text(attachments[]).text regex_match "((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))"
file.parse_text(attachments[]).text regex_match "(?:one|two|three) days?"
file.parse_text(attachments[]).text regex_match "\\d\\d hours"
file.parse_text(attachments[]).text regex_match "bc1q.{0,50}\\b"
file.parse_text(attachments[]).text regex_match "permanently delete|destroy (?:\\w+\\s*){0,4} (?:data|evidence|videos?)"
file.parse_text(attachments[]).text regex_match "pervert|perversion|masturbat"
file.parse_text(attachments[]).text regex_match "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off"
file.parse_text(attachments[]).text regex_match "sen[dt]\\s*(?:\\w+\\s*){0,2}\\s*to\\s*(?:\\w+\\s*){0,3}\\s*.{0,10}(contacts|media|family|friends)"
attachments.file_extension eq "txt"
or
any(headers.hops)
or
not
headers.hops.authentication_results.compauth.verdict in ["pass", "softpass"]
headers.hops.authentication_results.dmarc eq "fail"
any(headers.hops)
any(headers.hops.fields)
headers.hops.fields.name eq "X-Google-Group-Id"
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
not
profile.by_sender func_call "profile.by_sender().solicited"
or
and
any(ml.nlu_classifier(body.current_thread.text).intents)
ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
ml.nlu_classifier(body.current_thread.text).intents length_compare "0"
body.current_thread.text length_compare "500"
body.html.raw regex_match "<img[^>]+src=\"cid:"
attachments length_compare "2"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.html.raw | regex_match |
| field:"body.html.raw" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Free subdomain link with credential theft indicators
#Message contains a suspicious Recipients pattern, a link that uses a free subdomain provider, and has credential theft language on the linked page.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free subdomain host |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(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"
)
and (
(
(
length(recipients.to) == 0
or all(recipients.to, .display_name == "Undisclosed recipients")
)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
)
or (
length(recipients.to) == 1
and any(recipients.to, .email.email == sender.email.email)
)
or (
length(recipients.to) == 0
and length(recipients.cc) == 0
and length(recipients.bcc) > 0
)
)
and any(body.links,
any(file.explode(ml.link_analysis(.).screenshot),
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence != "low"
)
)
)
Detection logic
Scope: inbound message.
Message contains a suspicious Recipients pattern, a link that uses a free subdomain provider, and has credential theft language on the linked page.
- inbound message
any of
body.linkswhere all hold:- .href_url.domain.root_domain in $free_subdomain_hosts
- .href_url.domain.subdomain is set
- .href_url.domain.subdomain is not 'www'
any of:
all of:
any of:
- length(recipients.to) is 0
all of
recipients.towhere:- .display_name is 'Undisclosed recipients'
- length(recipients.cc) is 0
- length(recipients.bcc) is 0
all of:
- length(recipients.to) is 1
any of
recipients.towhere:- .email.email is sender.email.email
all of:
- length(recipients.to) is 0
- length(recipients.cc) is 0
- length(recipients.bcc) > 0
any of
body.linkswhere:any of
file.explode(...)where:any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, recipients.to[].email.email, sender.email.email, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier. Reference lists: $free_subdomain_hosts.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
recipients.to[].display_name | equals | Undisclosed recipients |
ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
any(body.links)
any(file.explode(...))
any(ml.nlu_classifier(file.explode(...).scan.ocr.raw).intents)
and
ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].confidence ne "low"
ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].name eq "cred_theft"
or
and
or
recipients.to length_compare "0"
macro "all(recipients.to)"
recipients.bcc length_compare "0"
recipients.cc length_compare "0"
and
any(recipients.to)
recipients.to.email.email cross_field_compare "sender.email.email"
recipients.to length_compare "1"
and
recipients.bcc length_compare "0"
recipients.cc length_compare "0"
recipients.to length_compare "0"
any(body.links)
and
body.links.href_url.domain.subdomain is_not_null
body.links.href_url.domain.subdomain ne "www"
macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
HTML smuggling containing recipient email address
#HTML attachment (or HTML attachment in attached email) is small and contains a recipients email address.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion, HTML smuggling, Scripting |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
any(attachments,
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or .content_type == "message/rfc822"
or .file_type == "html"
or (.content_type == "text/html" or .file_extension in ('eml'))
)
and any(file.explode(.),
.size < 10000
and length(.scan.strings.strings) < 20
and any(recipients.to,
any(..scan.strings.strings,
strings.icontains(., ..email.email)
)
and .email.domain.valid
)
)
)
or any(attachments,
(.file_extension in~ $file_extensions_common_archives)
and any(file.explode(.),
(
.file_extension in~ ("html", "htm", "shtml", "dhtml")
or ..file_type == "html"
or ..content_type == "text/html"
)
and .size < 10000
and length(.scan.strings.strings) < 20
and any(recipients.to,
any(..scan.strings.strings,
strings.icontains(., ..email.email)
)
and .email.domain.valid
)
)
)
)
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 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")
)
// unsolicited or fails authentation
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 (
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 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.
HTML attachment (or HTML attachment in attached email) is small and contains a recipients email address.
- inbound message
any of:
any of
attachmentswhere all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .content_type is 'message/rfc822'
- .file_type is 'html'
any of:
- .content_type is 'text/html'
- .file_extension in ('eml')
any of
file.explode(.)where all hold:- .size < 10000
- length(.scan.strings.strings) < 20
any of
recipients.towhere all hold:any of
.scan.strings.stringswhere:- strings.icontains(.)
- .email.domain.valid
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where all hold:any of:
- .file_extension in ('html', 'htm', 'shtml', 'dhtml')
- .file_type is 'html'
- .content_type is 'text/html'
- .size < 10000
- length(.scan.strings.strings) < 20
any of
recipients.towhere all hold:any of
.scan.strings.stringswhere:- strings.icontains(.)
- .email.domain.valid
not:
any of
attachmentswhere:any of
file.parse_eml(.).attachmentswhere:- .content_type is 'message/delivery-status'
not:
any of
attachmentswhere:- .content_type in ('message/delivery-status', 'text/calendar')
not:
all of:
- sender.display_name is 'Mail Delivery Subsystem'
- headers.message_id ends with 'pphosted.com>'
any of
headers.hopswhere all hold:- .index is 0
- .received.server.raw contains 'pphosted.com'
any of
attachmentswhere:- .content_type is 'message/rfc822'
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
all of:
- sender.email.domain.domain in $org_domains
not:
- coalesce(headers.auth_summary.dmarc.pass)
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].index, headers.hops[].received.server.raw, headers.message_id, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, file.parse_eml, profile.by_sender_email, strings.contains, strings.ends_with, strings.icontains. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains, $org_domains.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | member | html |
attachments[].file_extension | member | htm |
attachments[].file_extension | member | shtml |
attachments[].file_extension | member | dhtml |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_type | equals | html |
attachments[].content_type | equals | text/html |
attachments[].file_extension | member | eml |
file.explode(attachments[])[].file_extension | member | html |
file.explode(attachments[])[].file_extension | member | htm |
file.explode(attachments[])[].file_extension | member | shtml |
file.explode(attachments[])[].file_extension | member | dhtml |
Stages and Predicates
Stage 1: mql_rule
and
or
any(attachments)
and
any(file.explode(attachments))
and
any(recipients.to)
and
any(file.explode(attachments).scan.strings.strings)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.strings.strings[])"
recipients.to.email.domain.valid eq "true"
or
attachments.content_type eq "text/html"
attachments.file_type eq "html"
file.explode(attachments[])[].file_extension in ["dhtml", "htm", "html", "shtml"]
file.explode(attachments[])[].scan.strings.strings length_compare "20"
file.explode(attachments[])[].size lt "10000"
macro "attachments[].file_extension in file_extensions_common_archives"
any(attachments)
and
any(file.explode(attachments))
and
any(recipients.to)
and
any(file.explode(attachments).scan.strings.strings)
strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.strings.strings[])"
recipients.to.email.domain.valid eq "true"
file.explode(attachments[])[].scan.strings.strings length_compare "20"
file.explode(attachments[])[].size lt "10000"
or
attachments.content_type eq "message/rfc822"
attachments.content_type eq "text/html"
attachments.file_extension eq "eml"
attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
attachments.file_type eq "html"
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"
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"
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)"
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(attachments)
any(file.parse_eml(attachments).attachments)
file.parse_eml(attachments).attachments.content_type eq "message/delivery-status"
not
any(attachments)
attachments.content_type in ["message/delivery-status", "text/calendar"]
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
attachments | array_any | excludes:attachments | |
headers.message_id | ends_with | pphosted.com> | excludes:headers.message_id field:"headers.message_id" value:"pphosted.com>" |
sender.display_name | eq | Mail Delivery Subsystem | excludes:sender.display_name field:"sender.display_name" value:"Mail Delivery Subsystem" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Impersonation: Fake Gmail attachment
#Message detects fake Gmail attachments by inspecting the body of a message for elements found within Gmail's user interface for attachment. In expected use, these elements only appears within the gmail WebUI and not within the body of message. The presence of this within message indicates a fake attachment.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any([body.html.display_text, body.current_thread.text, body.plain.raw],
length(.) < 2500
and (
strings.icontains(., 'Scanned by Gmail')
or (
0 < regex.icount(., '\.pdf|\.(doc|xls|ppt)x?') < 3
and any(body.links,
regex.icontains(.display_text, 'd[ao0]wnl[ao0]{2}d all')
)
and length(body.links) < 4
)
)
and regex.icontains(.,
'[KM]b\b'
) // file size
)
// 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
)
// if the sender has been marked as malicious, but has FPs, don't alert
and (
(
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
or not profile.by_sender().any_messages_malicious_or_spam
)
Detection logic
Scope: inbound message.
Message detects fake Gmail attachments by inspecting the body of a message for elements found within Gmail's user interface for attachment. In expected use, these elements only appears within the gmail WebUI and not within the body of message. The presence of this within message indicates a fake attachment.
- inbound message
any of
[body.html.display_text, body.current_thread.text, body.plain.raw]where all hold:- length(.) < 2500
any of:
- . contains 'Scanned by Gmail'
all of:
all of:
- regex.icount(., '\\.pdf|\\.(doc|xls|ppt)x?') > 0
- regex.icount(., '\\.pdf|\\.(doc|xls|ppt)x?') < 3
any of
body.linkswhere:- .display_text matches 'd[ao0]wnl[ao0]{2}d all'
- length(body.links) < 4
- . matches '[KM]b\\b'
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
any of:
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
not:
- profile.by_sender().any_messages_malicious_or_spam
Inspects: body.current_thread.text, body.html.display_text, body.links, body.links[].display_text, body.plain.raw, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains, regex.icount, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | Scanned by Gmail |
regex.icount | regex | \.pdf|\.(doc|xls|ppt)x? |
regex.icontains | regex | d[ao0]wnl[ao0]{2}d all |
regex.icontains | regex | [KM]b\b |
Stages and Predicates
Stage 1: mql_rule
and
any([body.html.display_text, body.current_thread.text, body.plain.raw])
and
or
and
any(body.links)
body.links.display_text regex_match "d[ao0]wnl[ao0]{2}d all"
body.links length_compare "4"
regex.icount func_call "regex.icount([body.html.display_text, body.current_thread.text, body.plain.raw][], \"\\.pdf|\\.(doc|xls|ppt)x?\") < 3"
regex.icount func_call "regex.icount([body.html.display_text, body.current_thread.text, body.plain.raw][], \"\\.pdf|\\.(doc|xls|ppt)x?\") > 0"
[body.html.display_text, body.current_thread.text, body.plain.raw] contains "Scanned by Gmail"
[body.html.display_text, body.current_thread.text, body.plain.raw] length_compare "2500"
[body.html.display_text, body.current_thread.text, body.plain.raw] regex_match "[KM]b\\b"
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().any_messages_malicious_or_spam"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
MalwareBazaar: Malicious attachment hash (trusted reporters)
#Detects if an attachment's SHA256 hash matches a SHA256 hash reported as malware on MalwareBazaar by trusted reporters from untrusted senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
)
Detection logic
Scope: inbound message.
Detects if an attachment's SHA256 hash matches a SHA256 hash reported as malware on MalwareBazaar by trusted reporters from untrusted senders.
- inbound message
any of
attachmentswhere:- .sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
Inspects: attachments[].sha256, type.inbound. Reference lists: $abuse_ch_malwarebazaar_sha256_trusted_reporters.
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
macro "attachments[].sha256 in abuse_ch_malwarebazaar_sha256_trusted_reporters"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
MalwareBazaar: Malicious attachment hash in archive (trusted reporters)
#Detects if an arhive attachments contains a file that matches a SHA256 hash reported as malware on MalwareBazaar by trusted reporters.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_extension in~ $file_extensions_common_archives
and any(file.explode(.),
.scan.hash.sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
)
)
Detection logic
Scope: inbound message.
Detects if an arhive attachments contains a file that matches a SHA256 hash reported as malware on MalwareBazaar by trusted reporters.
- inbound message
any of
attachmentswhere all hold:- .file_extension in $file_extensions_common_archives
any of
file.explode(.)where:- .scan.hash.sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
Inspects: attachments[].file_extension, type.inbound. Sensors: file.explode. Reference lists: $abuse_ch_malwarebazaar_sha256_trusted_reporters, $file_extensions_common_archives.
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
macro "file.explode(attachments[])[].scan.hash.sha256 in abuse_ch_malwarebazaar_sha256_trusted_reporters"
macro "attachments[].file_extension in file_extensions_common_archives"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Non-RFC compliant calendar files from unsolicited sender
#Detects calendar (.ics) files that do not follow RFC standards by lacking required UID identifiers while containing specific calendar components (VTODO, VJOURNAL, VFREEBUSY, or VEVENT). Forged ICS calendar invites can be spoofed to seemingly originate from any sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Tactics and techniques | Evasion, ICS Phishing, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in $file_extensions_common_archives
or .file_extension == "ics"
or .content_type == "text/calendar"
)
and any(file.explode(.),
(.file_extension == "ics" or .flavors.mime == "text/calendar")
and any(.scan.ics.calendars,
any(.components,
.uid is null
and .type in (
'VEVENT',
'VJOURNAL',
'VFREEBUSY',
'VTODO'
)
)
)
)
)
and not profile.by_sender_email().any_messages_benign
Detection logic
Scope: inbound message.
Detects calendar (.ics) files that do not follow RFC standards by lacking required UID identifiers while containing specific calendar components (VTODO, VJOURNAL, VFREEBUSY, or VEVENT). Forged ICS calendar invites can be spoofed to seemingly originate from any sender.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_common_archives
- .file_extension is 'ics'
- .content_type is 'text/calendar'
any of
file.explode(.)where all hold:any of:
- .file_extension is 'ics'
- .flavors.mime is 'text/calendar'
any of
.scan.ics.calendarswhere:any of
.componentswhere all hold:- .uid is missing
- .type in ('VEVENT', 'VJOURNAL', 'VFREEBUSY', 'VTODO')
not:
- profile.by_sender_email().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.explode, profile.by_sender_email. Reference lists: $file_extensions_common_archives.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | ics |
attachments[].content_type | equals | text/calendar |
file.explode(attachments[])[].file_extension | equals | ics |
file.explode(attachments[])[].flavors.mime | equals | text/calendar |
file.explode(attachments[])[].scan.ics.calendars[].components[].type | member | VEVENT |
file.explode(attachments[])[].scan.ics.calendars[].components[].type | member | VJOURNAL |
file.explode(attachments[])[].scan.ics.calendars[].components[].type | member | VFREEBUSY |
file.explode(attachments[])[].scan.ics.calendars[].components[].type | member | VTODO |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
and
any(file.explode(attachments).scan.ics.calendars)
any(file.explode(attachments).scan.ics.calendars.components)
and
file.explode(attachments[])[].scan.ics.calendars[].components[].type in ["VEVENT", "VFREEBUSY", "VJOURNAL", "VTODO"]
file.explode(attachments[])[].scan.ics.calendars[].components[].uid is_null
or
file.explode(attachments[])[].file_extension eq "ics"
file.explode(attachments[])[].flavors.mime eq "text/calendar"
or
attachments.content_type eq "text/calendar"
attachments.file_extension eq "ics"
macro "attachments[].file_extension in file_extensions_common_archives"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
PDF attachment with Google (AE) redirecting to a php or zip file
#Detects a PDF attachment with a link that contains a Google.ae redirect URL.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Open redirect, PDF |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
.file_type == "pdf"
and any(file.explode(.),
any(.scan.pdf.urls,
// url encoded q=http
strings.starts_with(.query_params, "q=%68%74%74%70")
// url encoded .php or .zip
and (
strings.contains(.query_params, ".%70%68%70")
or strings.contains(.query_params, "%2e%7a%69%70")
)
and .domain.root_domain == "google.ae"
)
)
)
Detection logic
Scope: inbound message.
Detects a PDF attachment with a link that contains a Google.ae redirect URL.
- inbound message
any of
attachmentswhere all hold:- .file_type is 'pdf'
any of
file.explode(.)where:any of
.scan.pdf.urlswhere all hold:- .query_params starts with 'q=%68%74%74%70'
any of:
- .query_params contains '.%70%68%70'
- .query_params contains '%2e%7a%69%70'
- .domain.root_domain is 'google.ae'
Inspects: attachments[].file_type, type.inbound. Sensors: file.explode, strings.contains, strings.starts_with.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | pdf |
strings.starts_with | prefix | q=%68%74%74%70 |
strings.contains | substring | .%70%68%70 |
strings.contains | substring | %2e%7a%69%70 |
file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain | equals | google.ae |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.pdf.urls)
and
or
file.explode(attachments[])[].scan.pdf.urls[].query_params contains "%2e%7a%69%70"
file.explode(attachments[])[].scan.pdf.urls[].query_params contains ".%70%68%70"
file.explode(attachments[])[].scan.pdf.urls[].domain.root_domain eq "google.ae"
file.explode(attachments[])[].scan.pdf.urls[].query_params starts_with "q=%68%74%74%70"
attachments.file_type eq "pdf"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Suspicious attachment with unscannable Cloudflare link
#A PDF or Office document contains suspicious URLs that lead to Cloudflare-protected pages with turnstile CAPTCHA gates. The sender uses deceptive display names and subjects indicating urgency or authority.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, PDF, Social engineering, Impersonation: Employee, Impersonation: VIP |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in $file_extensions_macros
or .file_extension == "pdf"
or .file_type in ("pdf", "doc", "docx", "xls", "xlsx")
or .content_type in ("application/pdf")
)
and any(file.explode(.),
// few links
0 < length(.scan.url.urls) < 20
// fewer unique root domain links
and length(distinct(.scan.url.urls, .domain.root_domain)) < 10
// sender domain matches no body domains
and all(.scan.url.urls,
.domain.root_domain != 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?\.gov',
"Storage",
"Support",
"Sweepstakes",
"System",
"Tax",
"Tech Support",
"Update",
"Upgrade",
"Urgent",
"Validate",
"Verify",
"VIP",
"Webmaster",
"Winner",
)
or any(attachments,
(
.file_extension in $file_extensions_macros
or .file_extension == "pdf"
or .file_type in ("pdf", "doc", "docx", "xls", "xlsx")
or .content_type in ("application/pdf")
)
and any(file.explode(.),
any(.scan.url.urls, strings.ends_with(.url, ".exe"))
or any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft"
)
)
)
)
and any(attachments,
(
.file_extension in $file_extensions_macros
or .file_extension == "pdf"
or .file_type in ("pdf", "doc", "docx", "xls", "xlsx")
or .content_type in ("application/pdf")
)
and any(file.explode(.),
any(.scan.url.urls,
(
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"
)
)
)
)
)
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
)
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
A PDF or Office document contains suspicious URLs that lead to Cloudflare-protected pages with turnstile CAPTCHA gates. The sender uses deceptive display names and subjects indicating urgency or authority.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension is 'pdf'
- .file_type in ('pdf', 'doc', 'docx', 'xls', 'xlsx')
- .content_type in ('application/pdf')
any of
file.explode(.)where all hold:all of:
- length(.scan.url.urls) > 0
- length(.scan.url.urls) < 20
- length(distinct(.scan.url.urls, .domain.root_domain)) < 10
all of
.scan.url.urlswhere:- .domain.root_domain is not sender.email.domain.root_domain
not:
any of
attachmentswhere:- .content_type in ('message/global-delivery-status', 'message/delivery-status')
any of:
subject.subject matches any of 124 patterns
termination.*notice38417: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 .*disablaction.*requiredabandon.*packageabout.your.accountacc(ou)?n?t (is )?on ho[li]dacc(ou)?n?t.*terminatacc(oun)?t.*[il1]{2}mitationaccess.*limitationaccount (will be )?blockaccount.*de-?activataccount.*lockedaccount.*re-verificationaccount.*securityaccount.*suspensionaccount.has.beenaccount.has.expiredaccount.will.be.blockedaccount v[il]o[li]atactivity.*acc(oun)?talmost.fullapp[li]e.[il]dauthenticate.*accountbeen.*suspendclos.*of.*account.*processedconfirm.your.accountcourier.*ablecrediential.*notifdeactivation.*in.*progressdelivery.*attempt.*faileddocument.receiveddocumented.*shared.*with.*youdropbox.*documente-?ma[il1]+ .{010}suspene-?ma[il1]{1} usere-?ma[il1]{2} acce-?ma[il1]{2}.*up.?gradee.?ma[il1]{2}.*servere.?ma[il1]{2}.*suspendemail.updatefaxed youfraud(ulent)?.*chargefrom.helpdeskfu[il1]{2}.*ma[il1]+[ -]?boxhas.been.*suspendedhas.been.limitedhave.lockedhe[li]p ?desk upgradeheipdeski[il]iega[il]ii[il]ega[il]incoming e?mailincoming.*faxlock.*securityma[il1]{1}[ -]?box.*quoma[il1]{2}[ -]?box.*fu[il1]ma[il1]{2}box.*[il1]{2}mitma[il1]{2}box stormail on.?holdmail.*box.*migrationmail.*de-?activatmail.update.requiredmails.*pendingmessages.*pendingmissed.*shipping.*notificationmissed.shipment.notificationmust.update.your.accountnew [sl][io]g?[nig][ -]?in fromnew voice ?-?mailnotifications.*pendingoffice.*3.*6.*5.*suspendoffice365on google docs with youonline docpassword.*compromisedperiodic maintenancepotential(ly)? unauthorizedrefund not approvedreportrevised.*policyscamscanned.?invoicesecured?.updatesecurity breachsecurltysigned.*deliverystatement is readystatus of your .{314}? ?deliverysusp[il1]+c[il1]+ous.*act[il1]+v[il1]+tysuspicious.*sign.*[io]nsuspicious.activittemporar(il)?y deactivatetemporar[il1]{2}y disab[li]edtemporarily.*lockun-?usua[li].activityunable.*deliverunauthorized.*activitunauthorized.deviceundelivered messageunread.*docunusual.activityupgrade.*accountupgrade.noticeurgent messageurgent.verificationv[il1]o[li1]at[il1]on securityva[il1]{1}date.*ma[il1]{2}[ -]?boxverification ?-?requireverification( )?-?needverify.your?.accountweb ?-?ma[il1]{2}web[ -]?ma[il1]{2}will.be.suspendedyour (customer )?account .asyour.office.365your.online.access
any of
$suspicious_subjectswhere:- strings.icontains(subject.subject)
sender.display_name matches any of 73 patterns
AdminAdministratorAlertAssistantBillingBenefitsBonusCEOCFOCIOCTOChairmanClaimConfirmCriticalCustomer ServiceDealDiscountDirectorExclusiveExecutiveFaxFreeGift/bHR/bHelpdeskHuman ResourcesImmediateImportantInfoInformationInvoice\bIT\bLegalLotteryManagementManagerMember ServicesNotificationOfferOperationsOrderPartnerPaymentPayrollPresidentPremiumPrizeReceiptRefundRegistrarRequiredRewardSalesSecretarySecurityServiceSignatureSSA?\.govStorageSupportSweepstakesSystemTaxTech SupportUpdateUpgradeUrgentValidateVerifyVIPWebmasterWinner
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension is 'pdf'
- .file_type in ('pdf', 'doc', 'docx', 'xls', 'xlsx')
- .content_type in ('application/pdf')
any of
file.explode(.)where any holds:any of
.scan.url.urlswhere:- .url ends with '.exe'
any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere:- .name is 'cred_theft'
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
- .file_extension is 'pdf'
- .file_type in ('pdf', 'doc', 'docx', 'xls', 'xlsx')
- .content_type in ('application/pdf')
any of
file.explode(.)where:any of
.scan.url.urlswhere 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.linkswhere:- .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:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
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
not:
- profile.by_sender().any_messages_benign
Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.ends_with, strings.icontains, strings.ilike. Reference lists: $file_extensions_macros, $high_trust_sender_root_domains, $suspicious_subjects.
Indicators matched (208)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | pdf |
attachments[].file_type | member | pdf |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
attachments[].file_type | member | xls |
attachments[].file_type | member | xlsx |
attachments[].content_type | member | application/pdf |
regex.icontains | regex | termination.*notice |
regex.icontains | regex | 38417 |
regex.icontains | regex | :completed |
regex.icontains | regex | [il1]{2}mit.*ma[il1]{2} ?bo?x |
regex.icontains | regex | [il][il][il]egai[ -] |
196 more
regex.icontains | regex | [li][li][li]ega[li] attempt |
regex.icontains | regex | [ng]-?[io]n .*block |
regex.icontains | regex | [ng]-?[io]n .*cancel |
regex.icontains | regex | [ng]-?[io]n .*deactiv |
regex.icontains | regex | [ng]-?[io]n .*disabl |
regex.icontains | regex | action.*required |
regex.icontains | regex | abandon.*package |
regex.icontains | regex | about.your.account |
regex.icontains | regex | acc(ou)?n?t (is )?on ho[li]d |
regex.icontains | regex | acc(ou)?n?t.*terminat |
regex.icontains | regex | acc(oun)?t.*[il1]{2}mitation |
regex.icontains | regex | access.*limitation |
regex.icontains | regex | account (will be )?block |
regex.icontains | regex | account.*de-?activat |
regex.icontains | regex | account.*locked |
regex.icontains | regex | account.*re-verification |
regex.icontains | regex | account.*security |
regex.icontains | regex | account.*suspension |
regex.icontains | regex | account.has.been |
regex.icontains | regex | account.has.expired |
regex.icontains | regex | account.will.be.blocked |
regex.icontains | regex | account v[il]o[li]at |
regex.icontains | regex | activity.*acc(oun)?t |
regex.icontains | regex | almost.full |
regex.icontains | regex | app[li]e.[il]d |
regex.icontains | regex | authenticate.*account |
regex.icontains | regex | been.*suspend |
regex.icontains | regex | clos.*of.*account.*processed |
regex.icontains | regex | confirm.your.account |
regex.icontains | regex | courier.*able |
regex.icontains | regex | crediential.*notif |
regex.icontains | regex | deactivation.*in.*progress |
regex.icontains | regex | delivery.*attempt.*failed |
regex.icontains | regex | document.received |
regex.icontains | regex | documented.*shared.*with.*you |
regex.icontains | regex | dropbox.*document |
regex.icontains | regex | e-?ma[il1]+ .{010}suspen |
regex.icontains | regex | e-?ma[il1]{1} user |
regex.icontains | regex | e-?ma[il1]{2} acc |
regex.icontains | regex | e-?ma[il1]{2}.*up.?grade |
regex.icontains | regex | e.?ma[il1]{2}.*server |
regex.icontains | regex | e.?ma[il1]{2}.*suspend |
regex.icontains | regex | email.update |
regex.icontains | regex | faxed you |
regex.icontains | regex | fraud(ulent)?.*charge |
regex.icontains | regex | from.helpdesk |
regex.icontains | regex | fu[il1]{2}.*ma[il1]+[ -]?box |
regex.icontains | regex | has.been.*suspended |
regex.icontains | regex | has.been.limited |
regex.icontains | regex | have.locked |
regex.icontains | regex | he[li]p ?desk upgrade |
regex.icontains | regex | heipdesk |
regex.icontains | regex | i[il]iega[il] |
regex.icontains | regex | ii[il]ega[il] |
regex.icontains | regex | incoming e?mail |
regex.icontains | regex | incoming.*fax |
regex.icontains | regex | lock.*security |
regex.icontains | regex | ma[il1]{1}[ -]?box.*quo |
regex.icontains | regex | ma[il1]{2}[ -]?box.*fu[il1] |
regex.icontains | regex | ma[il1]{2}box.*[il1]{2}mit |
regex.icontains | regex | ma[il1]{2}box stor |
regex.icontains | regex | mail on.?hold |
regex.icontains | regex | mail.*box.*migration |
regex.icontains | regex | mail.*de-?activat |
regex.icontains | regex | mail.update.required |
regex.icontains | regex | mails.*pending |
regex.icontains | regex | messages.*pending |
regex.icontains | regex | missed.*shipping.*notification |
regex.icontains | regex | missed.shipment.notification |
regex.icontains | regex | must.update.your.account |
regex.icontains | regex | new [sl][io]g?[nig][ -]?in from |
regex.icontains | regex | new voice ?-?mail |
regex.icontains | regex | notifications.*pending |
regex.icontains | regex | office.*3.*6.*5.*suspend |
regex.icontains | regex | office365 |
regex.icontains | regex | on google docs with you |
regex.icontains | regex | online doc |
regex.icontains | regex | password.*compromised |
regex.icontains | regex | periodic maintenance |
regex.icontains | regex | potential(ly)? unauthorized |
regex.icontains | regex | refund not approved |
regex.icontains | regex | report |
regex.icontains | regex | revised.*policy |
regex.icontains | regex | scam |
regex.icontains | regex | scanned.?invoice |
regex.icontains | regex | secured?.update |
regex.icontains | regex | security breach |
regex.icontains | regex | securlty |
regex.icontains | regex | signed.*delivery |
regex.icontains | regex | statement is ready |
regex.icontains | regex | status of your .{314}? ?delivery |
regex.icontains | regex | susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty |
regex.icontains | regex | suspicious.*sign.*[io]n |
regex.icontains | regex | suspicious.activit |
regex.icontains | regex | temporar(il)?y deactivate |
regex.icontains | regex | temporar[il1]{2}y disab[li]ed |
regex.icontains | regex | temporarily.*lock |
regex.icontains | regex | un-?usua[li].activity |
regex.icontains | regex | unable.*deliver |
regex.icontains | regex | unauthorized.*activit |
regex.icontains | regex | unauthorized.device |
regex.icontains | regex | undelivered message |
regex.icontains | regex | unread.*doc |
regex.icontains | regex | unusual.activity |
regex.icontains | regex | upgrade.*account |
regex.icontains | regex | upgrade.notice |
regex.icontains | regex | urgent message |
regex.icontains | regex | urgent.verification |
regex.icontains | regex | v[il1]o[li1]at[il1]on security |
regex.icontains | regex | va[il1]{1}date.*ma[il1]{2}[ -]?box |
regex.icontains | regex | verification ?-?require |
regex.icontains | regex | verification( )?-?need |
regex.icontains | regex | verify.your?.account |
regex.icontains | regex | web ?-?ma[il1]{2} |
regex.icontains | regex | web[ -]?ma[il1]{2} |
regex.icontains | regex | will.be.suspended |
regex.icontains | regex | your (customer )?account .as |
regex.icontains | regex | your.office.365 |
regex.icontains | regex | your.online.access |
regex.icontains | regex | Admin |
regex.icontains | regex | Administrator |
regex.icontains | regex | Alert |
regex.icontains | regex | Assistant |
regex.icontains | regex | Billing |
regex.icontains | regex | Benefits |
regex.icontains | regex | Bonus |
regex.icontains | regex | CEO |
regex.icontains | regex | CFO |
regex.icontains | regex | CIO |
regex.icontains | regex | CTO |
regex.icontains | regex | Chairman |
regex.icontains | regex | Claim |
regex.icontains | regex | Confirm |
regex.icontains | regex | Critical |
regex.icontains | regex | Customer Service |
regex.icontains | regex | Deal |
regex.icontains | regex | Discount |
regex.icontains | regex | Director |
regex.icontains | regex | Exclusive |
regex.icontains | regex | Executive |
regex.icontains | regex | Fax |
regex.icontains | regex | Free |
regex.icontains | regex | Gift |
regex.icontains | regex | /bHR/b |
regex.icontains | regex | Helpdesk |
regex.icontains | regex | Human Resources |
regex.icontains | regex | Immediate |
regex.icontains | regex | Important |
regex.icontains | regex | Info |
regex.icontains | regex | Information |
regex.icontains | regex | Invoice |
regex.icontains | regex | \bIT\b |
regex.icontains | regex | Legal |
regex.icontains | regex | Lottery |
regex.icontains | regex | Management |
regex.icontains | regex | Manager |
regex.icontains | regex | Member Services |
regex.icontains | regex | Notification |
regex.icontains | regex | Offer |
regex.icontains | regex | Operations |
regex.icontains | regex | Order |
regex.icontains | regex | Partner |
regex.icontains | regex | Payment |
regex.icontains | regex | Payroll |
regex.icontains | regex | President |
regex.icontains | regex | Premium |
regex.icontains | regex | Prize |
regex.icontains | regex | Receipt |
regex.icontains | regex | Refund |
regex.icontains | regex | Registrar |
regex.icontains | regex | Required |
regex.icontains | regex | Reward |
regex.icontains | regex | Sales |
regex.icontains | regex | Secretary |
regex.icontains | regex | Security |
regex.icontains | regex | Service |
regex.icontains | regex | Signature |
regex.icontains | regex | SSA?\.gov |
regex.icontains | regex | Storage |
regex.icontains | regex | Support |
regex.icontains | regex | Sweepstakes |
regex.icontains | regex | System |
regex.icontains | regex | Tax |
regex.icontains | regex | Tech Support |
regex.icontains | regex | Update |
regex.icontains | regex | Upgrade |
regex.icontains | regex | Urgent |
regex.icontains | regex | Validate |
regex.icontains | regex | Verify |
regex.icontains | regex | VIP |
regex.icontains | regex | Webmaster |
regex.icontains | regex | Winner |
strings.ends_with | suffix | .exe |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
strings.icontains | substring | cloudflare |
strings.icontains | substring | https://challenges.cloudflare.com/turnstile/ |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
any(file.explode(attachments))
any(file.explode(attachments).scan.url.urls)
and
not
or
and
any(ml.link_analysis(file.explode(attachments).scan.url.urls, mode='aggressive').final_dom.links)
ml.link_analysis(file.explode(attachments).scan.url.urls, mode='aggressive').final_dom.links.href_url.query_params contains "utm_source=errorcode"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.display_text match "error code"
ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.url.urls[]).effective_url.domain.root_domain in (marketbeat.com)"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.display_text regex_match "cookie.{0,50}Cloudflare"
or
and
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.display_text length_compare "200"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.raw contains "https://challenges.cloudflare.com/turnstile/"
ml.link_analysis(file.explode(attachments[])[].scan.url.urls[], mode='aggressive').final_dom.display_text contains "cloudflare"
or
attachments.content_type eq "application/pdf"
attachments.file_extension eq "pdf"
attachments.file_type in ["doc", "docx", "pdf", "xls", "xlsx"]
macro "attachments[].file_extension in file_extensions_macros"
or
any(attachments)
and
any(file.explode(attachments))
or
any(file.explode(attachments).scan.url.urls)
file.explode(attachments).scan.url.urls.url ends_with ".exe"
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"
or
attachments.content_type eq "application/pdf"
attachments.file_extension eq "pdf"
attachments.file_type in ["doc", "docx", "pdf", "xls", "xlsx"]
macro "attachments[].file_extension in file_extensions_macros"
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?\\.gov"
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"
any(attachments)
and
any(file.explode(attachments))
and
distinct(file.explode(attachments[])[].scan.url.urls, file.explode(attachments[])[].domain.root_domain) length_compare "10"
file.explode(attachments[])[].scan.url.urls length_compare "0"
file.explode(attachments[])[].scan.url.urls length_compare "20"
macro "all(file.explode(attachments[])[].scan.url.urls)"
or
attachments.content_type eq "application/pdf"
attachments.file_extension eq "pdf"
attachments.file_type in ["doc", "docx", "pdf", "xls", "xlsx"]
macro "attachments[].file_extension in file_extensions_macros"
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
any(attachments)
attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
attachments | array_any | excludes:attachments |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.display_name | regex_match |
| field:"sender.display_name" kind:regex_match |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Suspicious VBA macros from untrusted sender
#Detects any VBA macro attachment that scores above a medium confidence threshold in the Sublime Macro Classifier.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware |
| Tactics and techniques | Macros |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and any(attachments,
(
.file_extension in~ $file_extensions_macros
or (
.file_extension is null
and .file_type == "unknown"
and .content_type == "application/octet-stream"
and .size < 100000000
)
)
and ml.macro_classifier(.).malicious
and ml.macro_classifier(.).confidence in ("high")
)
and (
profile.by_sender().prevalence in ("new", "outlier")
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
Detection logic
Scope: inbound message.
Detects any VBA macro attachment that scores above a medium confidence threshold in the Sublime Macro Classifier.
- inbound message
any of
attachmentswhere all hold:any of:
- .file_extension in $file_extensions_macros
all of:
- .file_extension is missing
- .file_type is 'unknown'
- .content_type is 'application/octet-stream'
- .size < 100000000
- ml.macro_classifier(.).malicious
- ml.macro_classifier(.).confidence in ('high')
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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, type.inbound. Sensors: ml.macro_classifier, profile.by_sender. Reference lists: $file_extensions_macros.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
attachments[].file_type | equals | unknown |
attachments[].content_type | equals | application/octet-stream |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
and
or
and
attachments.content_type eq "application/octet-stream"
attachments.file_extension is_null
attachments.file_type eq "unknown"
attachments.size lt "100000000"
macro "attachments[].file_extension in file_extensions_macros"
ml.macro_classifier func_call "ml.macro_classifier(attachments[]).confidence in (high)"
ml.macro_classifier func_call "ml.macro_classifier(attachments[]).malicious"
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |