Attachment: QR code with credential phishing indicators
Detects messages with between 1-3 attachments containing a QR code with suspicious credential theft indicators, such as: LinkAnalysis credential phishing conclusion, decoded QR code url traverses suspicious infrastructure, the final destination is in URLhaus, decoded URL downloads a zip or executable, leverages URL shorteners, known QR abused openredirects, and more.
Sublime rule (View on GitHub)
1name: "Attachment: QR code with credential phishing indicators"
2description: |
3 Detects messages with between 1-3 attachments containing a QR code with suspicious credential theft indicators, such as: LinkAnalysis credential phishing conclusion, decoded QR code url traverses suspicious infrastructure, the final destination is in URLhaus, decoded URL downloads a zip or executable, leverages URL shorteners, known QR abused openredirects, and more.
4type: "rule"
5severity: "medium"
6source: |
7 type.inbound
8 and (
9 1 <= length(attachments) < 3
10 or (
11 // if there are more than three attachments
12 3 <= length(attachments) < 20
13 // there are only pngs and pdf/docx
14 and length(distinct(map(attachments, .file_extension))) == 2
15 and all(distinct(map(attachments, .file_extension)),
16 . in ('png', 'pdf', 'docx')
17 )
18 and (
19 // multiple attachments mention common brands or other common common filenames
20 (
21 length(filter(attachments,
22 strings.icontains(.file_name, 'adobe')
23 or strings.icontains(.file_name, 'office')
24 or strings.icontains(.file_name, 'appstore')
25 or strings.icontains(.file_name, 'google')
26 or strings.icontains(.file_name, 'padlock')
27 or regex.icontains(.file_name, '\bdoc\b')
28 )
29 ) > 3
30 )
31 // the attachment name contains the SLD of a recipient
32 or any(filter(attachments, .file_extension in ('pdf', 'docx')),
33 any(filter(recipients.to, .email.domain.valid),
34 strings.icontains(..file_name, .email.domain.sld)
35 )
36 )
37 )
38 )
39 )
40
41 // Inspects image attachments for QR codes
42 and any(attachments,
43 (
44 .file_type in $file_types_images
45 or .file_type == "pdf"
46 or .file_extension in $file_extensions_macros
47 )
48 and (
49 any(file.explode(.),
50 .scan.qr.type == "url"
51 and not .scan.qr.url.domain.domain == "geico.app.link"
52 and (
53 // pass the QR URL to LinkAnalysis
54 any([ml.link_analysis(.scan.qr.url)],
55 .credphish.disposition == "phishing"
56
57 // any routing traverses via $suspicious_tld list
58 or any(.redirect_history, .domain.tld in $suspicious_tlds)
59
60 // effective destination in $suspicious_tld list
61 or .effective_url.domain.tld in $suspicious_tlds
62
63 // or the effective destination domain is in $abuse_ch_urlhaus_domains_trusted_reporters
64 or .effective_url.domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters
65
66 // or any files downloaded are zips or executables
67 or any(.files_downloaded,
68 .file_extension in $file_extensions_common_archives
69 or .file_extension in $file_extensions_executables
70 )
71 )
72 or (
73
74 // or the QR code's root domain is a url_shortener
75 .scan.qr.url.domain.root_domain in $url_shorteners
76 or (
77 .scan.qr.url.domain.root_domain in $social_landing_hosts
78 and (
79 not (
80 any(ml.nlu_classifier(body.current_thread.text).intents,
81 .name == "benign"
82 )
83 or any(ml.nlu_classifier(body.current_thread.text).entities,
84 .name == "disclaimer"
85 )
86 )
87 or not any(attachments,
88 any(file.explode(.),
89 any(ml.nlu_classifier(.scan.ocr.raw).intents,
90 .name == "benign"
91 )
92 )
93 )
94 // the QR code contains the email address of a recipient
95 or (
96 any(filter(recipients.to, .email.domain.valid),
97 strings.icontains(..scan.qr.url.url, .email.email)
98 or strings.decode_hex(..scan.qr.url.fragment) == .email.email
99 )
100 )
101 )
102
103 // exclude google maps
104 and not strings.starts_with(.scan.qr.url.url,
105 'https://goo.gl/maps'
106 )
107 and not strings.starts_with(.scan.qr.url.url,
108 'https://maps.app.goo.gl'
109 )
110 )
111 )
112
113 // the QR code url is a bing open redirect
114 or (
115 .scan.qr.url.domain.root_domain == 'bing.com'
116 and .scan.qr.url.path =~ '/ck/a'
117 )
118 // QR code contains non ascii chars
119 or regex.contains(.scan.qr.url.url, '[^\x00-\x7F]')
120 or (
121 (
122 // usap-dc open redirect
123 .scan.qr.url.domain.root_domain == "usap-dc.org"
124 and .scan.qr.url.path =~ "/tracker"
125 and strings.starts_with(.scan.qr.url.query_params,
126 "type=dataset&url=http"
127 )
128 )
129 // the QR code contains the email address of a recipient
130 // allowing for base64 encoded variants
131 or (
132 any(filter(recipients.to, .email.domain.valid),
133 strings.icontains(..scan.qr.url.url, .email.email)
134 or any(strings.scan_base64(..scan.qr.url.url,
135 ignore_padding=true
136 ),
137 strings.icontains(., ..email.email)
138 )
139 or any(strings.scan_base64(..scan.qr.url.fragment,
140 ignore_padding=true
141 ),
142 strings.icontains(., ..email.email)
143 )
144 or strings.decode_hex(..scan.qr.url.fragment) == .email.email
145 )
146 )
147 )
148 )
149 )
150 )
151 )
152 and (
153 (
154 profile.by_sender_email().prevalence in ("new", "outlier")
155 and not profile.by_sender_email().solicited
156 )
157 or (
158 profile.by_sender_email().any_messages_malicious_or_spam
159 and not profile.by_sender_email().any_messages_benign
160 )
161 or (
162 sender.email.domain.domain in $org_domains
163 and not coalesce(headers.auth_summary.dmarc.pass, false)
164 )
165 )
166
167 // negate highly trusted sender domains unless they fail DMARC authentication
168 and not (
169 sender.email.domain.root_domain in $high_trust_sender_root_domains
170 and coalesce(headers.auth_summary.dmarc.pass, false)
171 )
172attack_types:
173 - "Credential Phishing"
174tactics_and_techniques:
175 - "QR code"
176 - "Social engineering"
177detection_methods:
178 - "Computer Vision"
179 - "Header analysis"
180 - "Natural Language Understanding"
181 - "QR code analysis"
182 - "Sender analysis"
183 - "URL analysis"
184 - "URL screenshot"
185id: "9f1681e1-8c15-5edd-9aaa-eb5af1729322"