Extortion / sextortion (untrusted sender)
Detects extortion and sextortion attempts by analyzing the email body text from an untrusted sender.
Sublime rule (View on GitHub)
1name: "Extortion / sextortion (untrusted sender)"
2description: |
3 Detects extortion and sextortion attempts by analyzing the email body text from an untrusted sender.
4references:
5 - "https://krebsonsecurity.com/2018/07/sextortion-scam-uses-recipients-hacked-passwords/"
6type: "rule"
7severity: "low"
8source: |
9 type.inbound
10 and length(filter(body.links, .display_text is not null)) < 10
11 and not (
12 ml.nlu_classifier(body.current_thread.text).language == "english"
13 and any(ml.nlu_classifier(body.html.display_text).topics,
14 .name in (
15 "News and Current Events",
16 "Newsletters and Digests",
17 "Advertising and Promotions"
18 )
19 and .confidence in ("high", "medium")
20 )
21 )
22 and (
23 (
24 any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents,
25 (.name == "extortion" and .confidence == "high")
26 )
27 and (
28 any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text
29 )
30 ).entities,
31 .name == "financial"
32 or (
33 .name is not null
34 and regex.icontains(.text,
35 "cybḛ[rŗřṙȑȓɍʀɼɽг]c[rŗřṙȑȓɍʀɼɽг]imina[lĺļľḷḹḽłƖʟḻ]s"
36 )
37 )
38 )
39 or any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text
40 )
41 ).topics,
42 .name == "Financial Communications" and .confidence != "low"
43 )
44 )
45 )
46 // catches extortion content delivered as inline base64 images
47 or (
48 (body.current_thread.text is null or length(body.current_thread.text) < 10)
49 and any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
50 .name == "extortion" and .confidence == "high"
51 )
52 and (
53 any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).entities,
54 .name == "financial"
55 )
56 or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics,
57 .name == "Financial Communications" and .confidence != "low"
58 )
59 )
60 )
61 // manual indicators failsafe
62 or 3 of (
63 // malware terms
64 regex.icontains(strings.replace_confusables(body.current_thread.text),
65 "(?:(?:spy|[mṁ][aȁḁ]l)[wŵ][aȁḁ][rŗ]e|[tŢ][rŗȓ][oốởộ]j[aǻä][nņ]|[rȓ]emote (?:entry|cont[rř]o[lĺ])|infiltrat(?:ed|ion)|backdoor|vi[rṙ]us|intruder|(?:your|the).{0,15}(?:device|system|computer|phone).{0,10}(?:became|was|got|is).{0,5}comprom[ḯiïíįī]sed|prov[ḯiïíįī]d[ḯiïíįī]ng.{0,20}full [aảǡą]ccess)"
66 ),
67 // actions recorded
68 regex.icontains(strings.replace_confusables(body.current_thread.text),
69 "(?:p[oộ][rŗ]n|a[dȡ]ult (?:web)?site|webcam|mastu[rŗ]bating|je[rŗ]king off|pleasu[rŗȑ]i[nŋ]g you[rŗṛ]self|getting off|expli[cƈ]it|cl[ḯiïíįī]ps.{0,20}screenshots|NSFW|gr[aǻẳ]phic c[oỡở]ntent)"
70 ),
71 regex.icontains(strings.replace_confusables(body.current_thread.text),
72 "(?:pe[rŗ]ve[rŗ]t|pe[rŗ]ve[rŗ]sion|mastu[rŗ]bat)"
73 ),
74 // a timeframe to pay
75 regex.icontains(strings.replace_confusables(body.current_thread.text),
76 '[ilo0-9]{2} (?:hou[rŗṝ][sṣ]|uu[rŗ])',
77 '(?:one|tw[oờȍ]|2|th[rŗ]ee|\d) [dḍ][aảǡą]y[sṣ]?',
78 'set a timer'
79 ),
80 // a promise from the actor
81 regex.icontains(strings.replace_confusables(body.current_thread.text),
82 '(?:pe[rŗ]manently|will|I''ll) delete|([rŗ]emove|destroy) (?:[\p{L}\p{M}\p{N}]+\s*){0,4} (?:data|ev[ḯiïįīí]dence|v[ḯiïíįī]deos?)'
83 ),
84 // a threat from the actor
85 regex.icontains(strings.replace_confusables(body.current_thread.text),
86 '(?:\bsen[dt]|forward|expose|share)\s*(?:[\p{L}\p{N}]+\s*){0,5}\s*to\s*(?:[\p{L}\p{N}]+\s*){0,5}(?:contacts|media|family|f[rŗ]iends|coworkers|co-workers|associates|kin\b)'
87 ),
88 // bitcoin language (excluding newsletters)
89 (
90 regex.icontains(strings.replace_confusables(body.current_thread.text),
91 '[bḆḂ]it[cĉƈ][oöة]i[nņɲ]|\bbtc\b|blockchain'
92 )
93 // negate cryptocurrency newsletters
94 and not (
95 any(body.links,
96 strings.icontains(.display_text, "unsubscribe")
97 and (
98 strings.icontains(.href_url.path, "unsubscribe")
99 // handle mimecast URL rewrites
100 or (
101 .href_url.domain.root_domain == 'mimecastprotect.com'
102 and strings.icontains(.href_url.query_params,
103 sender.email.domain.root_domain
104 )
105 )
106 )
107 )
108 )
109 ),
110 (
111 regex.icontains(strings.replace_confusables(body.current_thread.text),
112 '(?:contact the police|(?:bitcoin|\bbtc\b).{0,20}(?:wallet|address))'
113 )
114 and regex.icontains(strings.replace_confusables(body.current_thread.text),
115 '(?:\b[13][a-km-zA-HJ-NP-Z0-9]{24,34}\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'
116 )
117 ),
118 regex.icontains(strings.replace_confusables(body.current_thread.text),
119 'bc1q.{0,50}\b'
120 ),
121 (
122 regex.count(body.current_thread.text,
123 '[\x{0300}-\x{036F}\x{1AB0}-\x{1AFF}\x{1DC0}-\x{1DFF}\x{0100}-\x{024F}\x{1E00}-\x{1EFF}]'
124 ) > 20
125 and length(body.current_thread.links) == 0
126 )
127 )
128 )
129 and (
130 not profile.by_sender().solicited
131 or (
132 profile.by_sender().any_messages_malicious_or_spam
133 and not profile.by_sender().any_messages_benign
134 )
135 or any(headers.hops, any(.fields, .name == "X-Google-Group-Id"))
136
137 // many extortion emails spoof sender domains and fail sender authentication
138 or (
139 not headers.auth_summary.dmarc.pass
140 or headers.auth_summary.dmarc.pass is null
141 or not headers.auth_summary.spf.pass
142 )
143 )
144 // negate legit bounce backs
145 and not any(ml.nlu_classifier(body.current_thread.text).topics,
146 .name in ("Bounce Back and Delivery Failure Notifications")
147 )
148 // negate legit forwards and replies
149 and not (
150 (subject.is_reply or subject.is_forward)
151 and length(body.previous_threads) > 0
152 and (length(headers.references) > 0 or headers.in_reply_to is not null)
153 )
154 // negate benign newsletters that mention cyber extortion
155 and not (
156 any(body.links,
157 strings.icontains(.display_text, "unsubscribe")
158 and strings.icontains(.href_url.path, "unsubscribe")
159 )
160 // newsletters are typically longer than the average extortion script
161 and length(body.current_thread.text) > 2000
162 )
163 and length(body.current_thread.text) < 8000
164 // negate highly trusted sender domains unless they fail DMARC authentication
165 and (
166 (
167 sender.email.domain.root_domain in $high_trust_sender_root_domains
168 and not headers.auth_summary.dmarc.pass
169 )
170 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
171 )
172
173attack_types:
174 - "Extortion"
175tactics_and_techniques:
176 - "Social engineering"
177 - "Spoofing"
178detection_methods:
179 - "Content analysis"
180 - "Header analysis"
181 - "Natural Language Understanding"
182 - "Sender analysis"
183id: "265913eb-2ccd-5f77-9a09-f6d8539fd2f6"