Detection rules › Sublime MQL
Reconnaissance: Large unknown recipient list
Recon messages, a form of deliverability testing, are used to validate whether a recipient address is valid or not, potentially preceding an attack. There's a large number of recipients that are unknown to the organization, no links or attachments, and a short body and subject from an unknown sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Reconnaissance |
Event coverage
Rule body MQL
type.inbound
and (
length(recipients.to) > 10
and length(filter(recipients.to,
.email.domain.domain not in $org_domains
and .email.email not in $recipient_emails
and (
.email.domain.valid
or strings.icontains(.display_name, "undisclosed")
)
)
) >= 10
)
and (
length(subject.subject) <= 10
or subject.subject == body.current_thread.text
or (subject.is_reply and length(body.previous_threads) == 0)
)
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 (
length(attachments) == 0
or (
length(attachments) == 1
and any(attachments,
.file_type in ("pdf", "png", "jpg", "tif", "heif", "doc", "docx")
and any(file.explode(.),
length(.scan.ocr.raw) < 20
or length(.scan.strings.strings) == 1
)
)
)
)
and (
body.current_thread.text is null
or length(body.current_thread.text) < 50
// body length without disclaimer is shorter than 50 characters
or (
any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
.name == "disclaimer"
),
.text
),
(length(body.current_thread.text) - length(.)) < 50
)
)
)
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 (
(
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.
Recon messages, a form of deliverability testing, are used to validate whether a recipient address is valid or not, potentially preceding an attack. There's a large number of recipients that are unknown to the organization, no links or attachments, and a short body and subject from an unknown sender.
- inbound message
all of:
- length(recipients.to) > 10
- length(filter(recipients.to, .email.domain.domain not in $org_domains and .email.email not in $recipient_emails and .email.domain.valid or strings.icontains(.display_name, 'undisclosed'))) ≥ 10
any of:
- length(subject.subject) ≤ 10
- subject.subject is body.current_thread.text
all of:
- subject.is_reply
- length(body.previous_threads) is 0
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:
- length(attachments) is 0
all of:
- length(attachments) is 1
any of
attachmentswhere all hold:- .file_type in ('pdf', 'png', 'jpg', 'tif', 'heif', 'doc', 'docx')
any of
file.explode(.)where any holds:- length(.scan.ocr.raw) < 20
- length(.scan.strings.strings) is 1
any of:
- body.current_thread.text is missing
- length(body.current_thread.text) < 50
any of
map(...)where:- length(body.current_thread.text) - length(.) < 50
- profile.by_sender().prevalence is not 'common'
not:
- profile.by_sender().solicited
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_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, body.previous_threads, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.domain, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.root_domain, subject.is_reply, subject.subject, type.inbound. Sensors: file.explode, ml.nlu_classifier, network.whois, profile.by_sender, strings.icontains. Reference lists: $high_trust_sender_root_domains, $org_domains, $recipient_emails.
Indicators matched (10)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | undisclosed |
body.links[].href_url.domain.domain | equals | aka.ms |
attachments[].file_type | member | pdf |
attachments[].file_type | member | png |
attachments[].file_type | member | jpg |
attachments[].file_type | member | tif |
attachments[].file_type | member | heif |
attachments[].file_type | member | doc |
attachments[].file_type | member | docx |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | disclaimer |