Detection rules › Sublime MQL
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 |
Event coverage
Rule body MQL
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"
)
)
)
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 beta.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(beta.parse_text(.).text,
"((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))"
),
// actions recorded
regex.icontains(beta.parse_text(.).text,
"porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off"
),
regex.icontains(beta.parse_text(.).text,
"pervert|perversion|masturbat"
),
// a timeframe to pay
regex.icontains(beta.parse_text(.).text,
'\d\d hours',
'(?:one|two|three) days?'
),
// a promise from the actor
regex.icontains(beta.parse_text(.).text,
'permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?)'
),
// a threat from the actor
regex.icontains(beta.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(beta.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(beta.parse_text(.).text,
"contact the police"
)
and regex.icontains(beta.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(beta.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'
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:
- beta.parse_text(.).text matches '((spy|mal)ware|trojan|remote control|infiltrat(ed|ion))'
- beta.parse_text(.).text matches 'porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off'
- beta.parse_text(.).text matches 'pervert|perversion|masturbat'
beta.parse_text(.).text matches any of 2 patterns
\d\d hours(?:one|two|three) days?
- beta.parse_text(.).text matches 'permanently delete|destroy (?:\\w+\\s*){0,4} (?:data|evidence|videos?)'
- beta.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:
- beta.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:
- beta.parse_text(.).text contains 'contact the police'
- beta.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'
- beta.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.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: beta.parse_text, file.explode, file.parse_text, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains. Reference lists: $file_types_images.
Indicators matched (25)
| Field | Match | Value |
|---|---|---|
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) |
regex.icontains | regex | bitcoin|\bbtc\b|blockchain |
13 more
strings.icontains | substring | unsubscribe |
body.links[].href_url.domain.root_domain | equals | mimecastprotect.com |
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 |
headers.hops[].authentication_results.compauth.verdict | member | pass |
headers.hops[].authentication_results.compauth.verdict | member | softpass |