Brand impersonation: QuickBooks
Impersonation of the Quickbooks service from Intuit.
Sublime rule (View on GitHub)
1name: "Brand impersonation: QuickBooks"
2description: "Impersonation of the Quickbooks service from Intuit."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7 and (
8 (
9 strings.ilike(sender.display_name,
10 'quickboo*',
11 'QuickB*',
12 'QBook*',
13 'intuit*'
14 )
15 or strings.like(sender.display_name, "QB-*", "QB *")
16 or regex.icontains(sender.display_name, '\bqb[o]?\b')
17 or strings.ilevenshtein(sender.display_name, 'quickbooks') <= 1
18 or strings.ilike(sender.email.domain.domain, '*quickbook*')
19 or (
20 length(filter(ml.nlu_classifier(body.current_thread.text).entities,
21 strings.icontains(.text, "quickbooks")
22 )
23 ) >= 2
24 and any(ml.nlu_classifier(body.current_thread.text).intents,
25 .name in ("cred_theft", "callback_scam")
26 )
27 )
28 or (
29 any(attachments,
30 length(filter(ml.nlu_classifier(beta.ocr(.).text).entities,
31 strings.icontains(.text, "quickbooks")
32 )
33 ) >= 2
34 and regex.icontains(beta.ocr(.).text,
35 '\+?(?:[ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
36 )
37 )
38 )
39 )
40 or strings.ilike(body.current_thread.text, "*invoice*")
41 )
42 and (
43 any(ml.logo_detect(file.message_screenshot()).brands,
44 .name == "Quickbooks" and .confidence in ("medium", "high")
45 )
46 or (
47 any(attachments,
48 (
49 any(ml.logo_detect(.).brands,
50 .name == "Quickbooks" and .confidence in ("medium", "high")
51 )
52 // the QuickBooks/Intuit logo lockup, footer or copyright in the
53 // attachment, mirroring the body-text markers used above
54 or regex.icontains(beta.ocr(.).text,
55 '©\s*(?:[0-9]{4})?\s*intuit\b',
56 'intuit\s+(?:inc|quickbooks)\b',
57 '@intuit\b',
58 'quickbooks\s+(?:billing|support|cloud\s+services|subscription)'
59 )
60 )
61 and any(ml.nlu_classifier(beta.ocr(.).text).intents,
62 .name in ("cred_theft", "callback_scam")
63 )
64 )
65 )
66 // contains the address and copyright
67 or (
68 strings.icontains(body.current_thread.text,
69 '2800 E. Commerce Center Place, Tucson, AZ 85706',
70 '2700 Coast Ave, Mountain View, CA 94043'
71 )
72 and regex.icontains(body.current_thread.text, '©\s*(?:\d+)\s*Intuit')
73 )
74 or strings.icontains(body.current_thread.text,
75 'Powered by QuickBooks',
76 'QuickBooks and Intuit are trademarks of Intuit Inc.',
77 "QuickBooks Cloud Services",
78 "QuickBooks Support Center",
79 "QuickBooks subscription"
80 )
81 or regex.icontains(body.current_thread.text,
82 '(?:Secured by )?QuickBooks Payments'
83 )
84 or regex.imatch(body.current_thread.text, '.*quickbooks\s\S+\spayroll')
85
86 // phone number and update language
87 or (
88 regex.icontains(body.current_thread.text,
89 '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
90 '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
91 )
92 and any(ml.nlu_classifier(body.current_thread.text).topics,
93 .name in ("Software and App Updates", "Security and Authentication")
94 )
95
96 // we need to re-check for QB indicators, otherwise we can have "*invoice*"
97 // and this block, which is much more than just QB impersonation
98 and (
99 strings.ilike(sender.display_name,
100 'quickbook*',
101 'QuickB*',
102 'QBook*',
103 'intuit*'
104 )
105 or strings.like(sender.display_name, "QB-*", "QB *")
106 or regex.icontains(sender.display_name, '\bqb[o]?\b')
107 or strings.ilevenshtein(sender.display_name, 'quickbooks') <= 1
108 or strings.ilike(sender.email.domain.domain, '*quickbook*')
109 or (
110 length(filter(ml.nlu_classifier(body.current_thread.text).entities,
111 strings.icontains(.text, "quickbooks")
112 )
113 ) > 2
114 and any(ml.nlu_classifier(body.current_thread.text).intents,
115 .name == "cred_theft"
116 )
117 )
118 )
119 )
120 or (
121 sender.email.domain.domain in $free_email_providers
122 and any(headers.domains, .root_domain == "sendgrid.net")
123 and any(ml.nlu_classifier(body.current_thread.text).entities,
124 .name == "org" and .text == "Quickbooks"
125 )
126 )
127 or any(body.links,
128 (
129 regex.icontains(.display_url.url, '(?:quickbooks|intuit)')
130 and .mismatched
131 and not .href_url.domain.root_domain in (
132 "mimecast.com",
133 "mimecastprotect.com"
134 )
135 )
136 or (
137 regex.icontains(.href_url.path, '(?:quickbooks|intuit)')
138 and not strings.icontains(.href_url.domain.root_domain,
139 "quickbooks",
140 "intuit"
141 )
142 and not any(ml.nlu_classifier(body.current_thread.text).topics,
143 .name == "Advertising and Promotions"
144 )
145 )
146 )
147 or (
148 regex.icontains(body.current_thread.text, "quickbooks?", 'intuit\b')
149 and any(ml.nlu_classifier(body.current_thread.text).entities,
150 .name == "sender"
151 and (
152 regex.icontains(.text,
153 'quickbooks?',
154 'intuit (services?|\bach\b)'
155 )
156 or regex.icontains(.text, '\bqb[o]?\b')
157 )
158 )
159 and any(ml.nlu_classifier(body.current_thread.text).intents,
160 .name == "cred_theft" and .confidence == "high"
161 )
162 )
163 )
164 and not (
165 sender.email.domain.root_domain in~ (
166 'intuit.com',
167 'turbotax.com',
168 'intuit.ca',
169 'meliopayments.com',
170 'qemailserver.com',
171 'intuit.co.uk',
172 'quickbooksonline.com',
173 'tsheets.com'
174 )
175 and coalesce(headers.auth_summary.dmarc.pass, false)
176 )
177 and (
178 not profile.by_sender().any_messages_benign
179 and not profile.by_sender().solicited
180 )
181 // links in body are not known QB domains or the senders root website (both indicative of a legitimate QuickBooks invoice message)
182 and (
183 length(filter(body.links,
184 .href_url.domain.root_domain in~ (
185 'intuit.com',
186 'turbotax.com',
187 'intuit.ca',
188 'meliopayments.com',
189 'qemailserver.com',
190 'intuit.co.uk',
191 'quickbooksonline.com'
192 )
193 or (
194 .href_url.domain.root_domain == sender.email.domain.root_domain
195 and (.href_url.path is null or .href_url.path == "/")
196 )
197 // handle links to the root website when the sender uses a freemail address to send invoices
198 or (
199 .href_url.domain.sld == sender.email.local_part
200 and (.href_url.path is null or .href_url.path == "/")
201 and sender.email.domain.root_domain in $free_email_providers
202 )
203 )
204 ) != length(body.links)
205 // or no valid links
206 or length(filter(body.links, .href_url.domain.domain is not null)) == 0
207 )
208 // the call to action link does not lead to inuit
209 and not (
210 // filter down to observed call to action display text
211 any(filter(body.links,
212 .display_text in~ (
213 "view and pay",
214 "review and pay",
215 "view details"
216 )
217 ),
218 // benign/legit href_url details for those links
219 (
220 // sendgrid rewritten links
221 .href_url.domain.domain == "links.notification.intuit.com"
222 // CTA link
223 or (
224 .href_url.domain.domain == "connect.intuit.com"
225 and strings.icontains(.href_url.query_params, 'cta=viewinvoicenow')
226 )
227 // Mimecast links
228 or (
229 .href_url.domain.root_domain == "mimecastprotect.com"
230 and (
231 strings.icontains(.href_url.query_params,
232 'domain=links.notification.intuit.com'
233 )
234 or strings.icontains(.href_url.query_params,
235 'domain=connect.intuit.com'
236 )
237 )
238 )
239 )
240 )
241 )
242 // negate common sender of quickbooks reseller
243 and not coalesce(strings.icontains(body.current_thread.text,
244 'Purchasing Reviews, Inc'
245 ),
246 false
247 )
248 // negate highly trusted sender domains unless they fail DMARC authentication
249 and not (
250 sender.email.domain.root_domain in $high_trust_sender_root_domains
251 and coalesce(headers.auth_summary.dmarc.pass, false)
252 )
253attack_types:
254 - "Callback Phishing"
255 - "Credential Phishing"
256tactics_and_techniques:
257 - "Impersonation: Brand"
258 - "Social engineering"
259detection_methods:
260 - "Computer Vision"
261 - "Content analysis"
262 - "Header analysis"
263 - "Sender analysis"
264id: "4fd791d1-a053-5c2d-80dd-c6dcdc112a62"