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