Detection rules › Sublime MQL
Free email provider sender with mismatched provider reply-to
Detects when a sender using a free email provider includes a reply-to address from a different free email provider, which is a common social engineering tactic.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Free email provider, Social engineering |
Event coverage
Rule body MQL
type.inbound
and sender.email.domain.root_domain in $free_email_providers
and length(headers.reply_to) > 0
and any(headers.reply_to,
.email.domain.root_domain in $free_email_providers
and .email.domain.root_domain != sender.email.domain.root_domain
and .email.domain.root_domain not in ("googlegroups.com")
)
// secureserver.net seems to rewrite the sender local part to be the reply-to domain for bounces
// observed in many newsletter sent via secureserver.net
and not (
strings.istarts_with(sender.email.domain.domain, 'bounces.')
and sender.email.domain.root_domain == 'secureserver.net'
and all(headers.reply_to,
strings.istarts_with(sender.email.local_part, .email.local_part)
and strings.iends_with(sender.email.local_part, .email.domain.domain)
)
)
// lists.riseup.net send from the list address and use the reply-to of the sender
// the sender is within the X-Original-From header and contains the full "From" header
and not (
sender.email.domain.domain == "lists.riseup.net"
and any(headers.hops,
any(.fields,
.name =~ "X-Original-From"
and any(headers.reply_to,
strings.icontains(..value, .email.email)
)
)
)
)
Detection logic
Scope: inbound message.
Detects when a sender using a free email provider includes a reply-to address from a different free email provider, which is a common social engineering tactic.
- inbound message
- sender.email.domain.root_domain in $free_email_providers
- length(headers.reply_to) > 0
any of
headers.reply_towhere all hold:- .email.domain.root_domain in $free_email_providers
- .email.domain.root_domain is not sender.email.domain.root_domain
- .email.domain.root_domain not in ('googlegroups.com')
not:
all of:
- sender.email.domain.domain starts with 'bounces.'
- sender.email.domain.root_domain is 'secureserver.net'
all of
headers.reply_towhere all hold:- strings.istarts_with(sender.email.local_part)
- strings.iends_with(sender.email.local_part)
not:
all of:
- sender.email.domain.domain is 'lists.riseup.net'
any of
headers.hopswhere:any of
.fieldswhere all hold:- .name is 'X-Original-From'
any of
headers.reply_towhere:- strings.icontains(.value)
Inspects: headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.reply_to, headers.reply_to[].email.domain.domain, headers.reply_to[].email.domain.root_domain, headers.reply_to[].email.email, headers.reply_to[].email.local_part, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: strings.icontains, strings.iends_with, strings.istarts_with. Reference lists: $free_email_providers.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
headers.reply_to[].email.domain.root_domain | member | googlegroups.com |
strings.istarts_with | prefix | bounces. |
sender.email.domain.root_domain | equals | secureserver.net |
sender.email.domain.domain | equals | lists.riseup.net |
headers.hops[].fields[].name | equals | X-Original-From |