Detection rules › Sublime MQL
Spam: Commonly observed formatting of unauthorized free giveaways
Detects commonly observed formatting of unauthorized giveaways, free tools, and products by multiple different brands.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Spam |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Event coverage
| Message attribute |
|---|
| body |
| body.links (collection) |
| sender |
| subject |
| type |
Rule body MQL
type.inbound
and (
(
any(html.xpath(body.html, "//div[contains(@style, 'BACKGROUND: URL')]").nodes,
.raw is not null
)
)
or (
any(body.links,
any([
"blob.core.windows.net",
"click.email.formula1.com",
"firmy-praha.eu"
],
..href_url.domain.domain == .
or strings.ends_with(..href_url.domain.domain, .)
)
)
)
)
and (
(
// subject has # plus random characters only
regex.icontains(subject.base, "#[a-z0-9]{5,}?")
// plus one of these
and (
// display name has a # + random characters only
regex.icontains(sender.display_name, "#[a-z0-9]{5,}?")
// subject starts with a period (yes, both subject cases should be true)
or strings.starts_with(subject.base, ".")
// Display name contains at least 2 emojis
or length(distinct(map(regex.extract(sender.display_name,
'(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
),
.full_match
)
)
) >= 2
)
)
or (
// Subject contains at least 2 emojias
length(distinct(map(regex.extract(subject.base,
'(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
),
.full_match
)
)
) >= 2
)
or
// another variant with different strings that have numbers but the same pattern is in both subject and displayname
(
// subject has # plus random characters & numbers
regex.icontains(subject.base, "#[1-9a-z]+")
// plus one of these
and (
regex.icontains(sender.display_name, "#[1-9a-z]+")
or strings.icontains(sender.display_name, "rewards")
)
)
or (
// or prornotions (promotions) once confusables are stripped in subject
strings.icontains(strings.replace_confusables(subject.base), "prornotions")
// and rewards in display name
and strings.icontains(sender.display_name, "rewards")
)
or (
// subject has * plus 4 random characters and numbers *
regex.icontains(subject.base, '\*[1-9a-z]{4,}\*')
// same with the display name
and regex.icontains(sender.display_name, '\*[1-9a-z]{4,}\*')
)
or (
// subject and display name has two *
strings.count(subject.base, "*") == 2
and strings.count(sender.display_name, "*") == 2
)
or (
// subject has string of random characters and numbers
// checking if string has 1 uppercase, 1 lowercase and 1 number
any(regex.extract(subject.base, '(?:-{1,2}|\s)([a-zA-Z0-9]{11,})'),
regex.contains(.full_match, '[A-Z]')
and regex.contains(.full_match, '[a-z]')
and regex.contains(.full_match, '[0-9]')
// some matches are legit but they are 35+ characters
and length(.full_match) <= 30
)
// negating support thread email subjects containg multiple : in their IDs
and not regex.count(subject.base, ':') > 5
)
)
Detection logic
Scope: inbound message.
Detects commonly observed formatting of unauthorized giveaways, free tools, and products by multiple different brands.
- inbound message
any of:
any of
html.xpath(body.html, "//div[contains(@style, 'BACKGROUND: URL')]").nodeswhere:- .raw is set
any of
body.linkswhere:any of
['blob.core.windows.net', 'click.email.formula1.com', 'firmy-praha.eu']where any holds:- .href_url.domain.domain is .
- strings.ends_with(.href_url.domain.domain)
any of:
all of:
- subject.base matches '#[a-z0-9]{5,}?'
any of:
- sender.display_name matches '#[a-z0-9]{5,}?'
- subject.base starts with '.'
- length(distinct(map(regex.extract(sender.display_name, '(?P<emoji>[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}])'), .full_match))) ≥ 2
- length(distinct(map(regex.extract(subject.base, '(?P<emoji>[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}])'), .full_match))) ≥ 2
all of:
- subject.base matches '#[1-9a-z]+'
any of:
- sender.display_name matches '#[1-9a-z]+'
- sender.display_name contains 'rewards'
all of:
- strings.replace_confusables(subject.base) contains 'prornotions'
- sender.display_name contains 'rewards'
all of:
- subject.base matches '\\*[1-9a-z]{4,}\\*'
- sender.display_name matches '\\*[1-9a-z]{4,}\\*'
all of:
- strings.count(subject.base, '*') is 2
- strings.count(sender.display_name, '*') is 2
all of:
any of
regex.extract(subject.base)where all hold:- .full_match matches '[A-Z]'
- .full_match matches '[a-z]'
- .full_match matches '[0-9]'
- length(.full_match) ≤ 30
not:
- regex.count(subject.base, ':') > 5
Inspects: body.html, body.links, body.links[].href_url.domain.domain, sender.display_name, subject.base, type.inbound. Sensors: html.xpath, regex.contains, regex.count, regex.extract, regex.icontains, strings.count, strings.ends_with, strings.icontains, strings.replace_confusables, strings.starts_with.
Indicators matched (12)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | #[a-z0-9]{5,}? |
strings.starts_with | prefix | . |
regex.extract | regex | (?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]) |
regex.icontains | regex | #[1-9a-z]+ |
strings.icontains | substring | rewards |
strings.icontains | substring | prornotions |
regex.icontains | regex | \*[1-9a-z]{4,}\* |
regex.extract | regex | (?:-{1,2}|\s)([a-zA-Z0-9]{11,}) |
regex.contains | regex | [A-Z] |
regex.contains | regex | [a-z] |
regex.contains | regex | [0-9] |
regex.count | regex | : |