Detection rules › Sublime MQL
Callback phishing: Branded invoice from sender/reply-to domain less than 30 days old
This rule checks for invoicing content from a sender, reply-to domain or return-path domain less than 30d old. It also checks the body or the OCR'd screenshot for key words commonly abused in fraudulent invoicing attacks.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Callback Phishing |
| Tactics and techniques | Impersonation: Brand, Out of band pivot, Social engineering |
Event coverage
Rule body MQL
type.inbound
// reply to domain that's less than 30d old and doesn't match the sender
and (
(
length(headers.reply_to) > 0
and all(headers.reply_to,
network.whois(.email.domain).days_old <= 30
and .email.email != sender.email.email
)
)
// or the return path or sender domain is less than 30d old
or network.whois(headers.return_path.domain).days_old <= 30
or network.whois(sender.email.domain).days_old <= 30
)
// invoicing with high confidence
and any(ml.nlu_classifier(body.current_thread.text).tags,
.name == "invoice" and .confidence == "high"
)
// commonly abused brands in body
and (
strings.ilike(body.current_thread.text,
"*mcafee*",
"*norton*",
"*geek squad*",
"*paypal*",
"*ebay*",
"*symantec*",
"*best buy*",
"*lifelock*",
"*virus*"
)
// commonly abused brand logo
or any(ml.logo_detect(file.message_screenshot()).brands,
.name in ("PayPal", "Norton", "GeekSquad", "Ebay")
)
// check message screenshot ocr for commonly abused brands
//
// 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 1 of (
strings.icontains(beta.ocr(file.message_screenshot()).text, "geek squad"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "lifelock"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "best buy"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "mcafee"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "norton"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "ebay"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "paypal"),
strings.icontains(beta.ocr(file.message_screenshot()).text, "virus"),
)
)
// phone number regex
and regex.icontains(body.current_thread.text,
'\+?(\d{1}.)?\(?\d{3}?\)?.\d{3}.?\d{4}'
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
This rule checks for invoicing content from a sender, reply-to domain or return-path domain less than 30d old. It also checks the body or the OCR'd screenshot for key words commonly abused in fraudulent invoicing attacks.
- inbound message
any of:
all of:
- length(headers.reply_to) > 0
all of
headers.reply_towhere all hold:- network.whois(.email.domain).days_old ≤ 30
- .email.email is not sender.email.email
- network.whois(headers.return_path.domain).days_old ≤ 30
- network.whois(sender.email.domain).days_old ≤ 30
any of
ml.nlu_classifier(body.current_thread.text).tagswhere all hold:- .name is 'invoice'
- .confidence is 'high'
any of:
body.current_thread.text matches any of 9 patterns
*mcafee**norton**geek squad**paypal**ebay**symantec**best buy**lifelock**virus*
any of
ml.logo_detect(file.message_screenshot()).brandswhere:- .name in ('PayPal', 'Norton', 'GeekSquad', 'Ebay')
at least 1 of 8: beta.ocr(file.message_screenshot()).text contains any of 8 patterns
geek squadlifelockbest buymcafeenortonebaypaypalvirus
- body.current_thread.text matches '\\+?(\\d{1}.)?\\(?\\d{3}?\\)?.\\d{3}.?\\d{4}'
not:
- profile.by_sender().solicited
not:
- profile.by_sender().any_messages_benign
Inspects: body.current_thread.text, headers.reply_to, headers.reply_to[].email.domain, headers.reply_to[].email.email, headers.return_path.domain, sender.email.domain, sender.email.email, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, network.whois, profile.by_sender, regex.icontains, strings.icontains, strings.ilike.
Indicators matched (24)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).tags[].name | equals | invoice |
ml.nlu_classifier(body.current_thread.text).tags[].confidence | equals | high |
strings.ilike | substring | *mcafee* |
strings.ilike | substring | *norton* |
strings.ilike | substring | *geek squad* |
strings.ilike | substring | *paypal* |
strings.ilike | substring | *ebay* |
strings.ilike | substring | *symantec* |
strings.ilike | substring | *best buy* |
strings.ilike | substring | *lifelock* |
strings.ilike | substring | *virus* |
ml.logo_detect(file.message_screenshot()).brands[].name | member | PayPal |
12 more
ml.logo_detect(file.message_screenshot()).brands[].name | member | Norton |
ml.logo_detect(file.message_screenshot()).brands[].name | member | GeekSquad |
ml.logo_detect(file.message_screenshot()).brands[].name | member | Ebay |
strings.icontains | substring | geek squad |
strings.icontains | substring | lifelock |
strings.icontains | substring | best buy |
strings.icontains | substring | mcafee |
strings.icontains | substring | norton |
strings.icontains | substring | ebay |
strings.icontains | substring | paypal |
strings.icontains | substring | virus |
regex.icontains | regex | \+?(\d{1}.)?\(?\d{3}?\)?.\d{3}.?\d{4} |