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