Callback phishing via Intuit service abuse

Callback phishing campaigns have been observed abusing Intuit Quickbooks services to send fraudulent invoices with callback phishing contents.

Sublime rule (View on GitHub)

  1name: "Callback phishing via Intuit service abuse"
  2description: "Callback phishing campaigns have been observed abusing Intuit Quickbooks services to send fraudulent invoices with callback phishing contents."
  3type: "rule"
  4severity: "medium"
  5source: |
  6  type.inbound
  7  
  8  // Legitimate Intuit sending infratructure
  9  and (
 10    sender.email.domain.root_domain in ('intuit.com', 'intuit.co.uk')
 11    // check for SPF or DMARC passed
 12    and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
 13  )
 14  and (
 15    // Callback Phishing in body (brand names required)
 16    (
 17      length(attachments) == 0
 18  
 19      // brand names are required.
 20      and regex.icontains(body.current_thread.text,
 21                          (
 22                            "mcafee|norton|geek.{0,5}squad|paypal|ebay|symantec|best buy|lifelock"
 23                          )
 24      )
 25      and 3 of (
 26        strings.ilike(body.current_thread.text, '*purchase*'),
 27        strings.ilike(body.current_thread.text, '*payment*'),
 28        strings.ilike(body.current_thread.text, '*transaction*'),
 29        strings.ilike(body.current_thread.text, '*subscription*'),
 30        strings.ilike(body.current_thread.text, '*antivirus*'),
 31        strings.ilike(body.current_thread.text, '*order*'),
 32        strings.ilike(body.current_thread.text, '*support*'),
 33        strings.ilike(body.current_thread.text, '*help line*'),
 34        strings.ilike(body.current_thread.text, '*receipt*'),
 35        strings.ilike(body.current_thread.text, '*invoice*'),
 36        strings.ilike(body.current_thread.text, '*call*'),
 37        strings.ilike(body.current_thread.text, '*cancel*'),
 38        strings.ilike(body.current_thread.text, '*renew*'),
 39        strings.ilike(body.current_thread.text, '*refund*')
 40      )
 41      // phone number regex
 42      and any([body.current_thread.text, subject.subject],
 43              regex.icontains(., '\b\+?(\d{1}.)?\(?\d{3}?\)?.\d{3}.?\d{4}\b')
 44      )
 45    )
 46    // Callback Phishing in the "billtoContent"
 47    or 
 48    // icontains a phone number
 49    (
 50      regex.icontains(strings.replace_confusables(body.html.inner_text),
 51                      '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+\+?(\d{1}.)?\(?\d{3}?\)?.\d{3}.?\d{4}.*\n'
 52      )
 53      or regex.icontains(strings.replace_confusables(body.html.inner_text),
 54                         '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+\+\d{1,3}[0-9]{10}.*\n'
 55      )
 56      or // +12028001238
 57   regex.icontains(strings.replace_confusables(body.html.inner_text),
 58                   '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+[0-9]{3}\.[0-9]{3}\.[0-9]{4}.*\n'
 59      )
 60      or // 202-800-1238
 61   regex.icontains(strings.replace_confusables(body.html.inner_text),
 62                   '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+[0-9]{3}-[0-9]{3}-[0-9]{4}.*\n'
 63      )
 64      or // (202) 800-1238
 65   regex.icontains(strings.replace_confusables(body.html.inner_text),
 66                   '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+\([0-9]{3}\)\s[0-9]{3}-[0-9]{4}.*\n'
 67      )
 68      or // (202)-800-1238
 69   regex.icontains(strings.replace_confusables(body.html.inner_text),
 70                   '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+\([0-9]{3}\)-[0-9]{3}-[0-9]{4}.*\n'
 71      )
 72      or // 202 800 1238
 73   regex.icontains(strings.replace_confusables(body.html.inner_text),
 74                   '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+1\s?[0-9]{3} [0-9]{3} [0-9]{4}.*\n'
 75      ) // 8123456789
 76      or (
 77        regex.icontains(strings.replace_confusables(body.html.inner_text),
 78                        '(?:Sold|Bill)[\s\xa0]To(?:\:\s+|\n)[^\n]+8\d{9}.*\n'
 79        )
 80        and regex.icontains(strings.replace_confusables(body.html.inner_text),
 81                            '\+1'
 82        )
 83      )
 84    )
 85    // all attachments are PDFs with callback phishing indicators Brands Required
 86    or (
 87      length(attachments) < 3
 88      and all(attachments, .file_extension == "pdf")
 89      // the attachment is a pdf with 1 page, and at least 60 ocr chars
 90      and any(attachments,
 91              (
 92                .file_extension == "pdf"
 93                and any(file.explode(.), .scan.exiftool.page_count < 3)
 94                and any(file.explode(.), length(.scan.ocr.raw) > 60)
 95  
 96                // 4 of the following strings are found        
 97                and (
 98                  any(file.explode(.),
 99                      4 of (
100                        strings.icontains(.scan.ocr.raw, "purchase"),
101                        strings.icontains(.scan.ocr.raw, "payment"),
102                        strings.icontains(.scan.ocr.raw, "transaction"),
103                        strings.icontains(.scan.ocr.raw, "subscription"),
104                        strings.icontains(.scan.ocr.raw, "antivirus"),
105                        strings.icontains(.scan.ocr.raw, "order"),
106                        strings.icontains(.scan.ocr.raw, "support"),
107                        strings.icontains(.scan.ocr.raw, "help line"),
108                        strings.icontains(.scan.ocr.raw, "receipt"),
109                        strings.icontains(.scan.ocr.raw, "invoice"),
110                        strings.icontains(.scan.ocr.raw, "call"),
111                        strings.icontains(.scan.ocr.raw, "helpdesk"),
112                        strings.icontains(.scan.ocr.raw, "cancel"),
113                        strings.icontains(.scan.ocr.raw, "renew"),
114                        strings.icontains(.scan.ocr.raw, "refund"),
115                        strings.icontains(.scan.ocr.raw, "amount"),
116                        strings.icontains(.scan.ocr.raw, "crypto"),
117                        strings.icontains(.scan.ocr.raw, "wallet address"),
118                        regex.icontains(.scan.ocr.raw, '\$\d{3}\.\d{2}\b'),
119                        regex.icontains(.scan.ocr.raw,
120                                        '(\+\d|1.(\()?\d{3}(\))?\D\d{3}\D\d{4})'
121                        ),
122                        regex.icontains(.scan.ocr.raw,
123                                        '\+?(\d{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}\d{3}[\s\.\-⋅]{0,5}\d{4}'
124                        )
125                      )
126  
127                      // 1 of the following strings is found, representing common Callback brands          
128                      and (
129                        1 of (
130                          strings.icontains(.scan.ocr.raw, "geek squad"),
131                          strings.icontains(.scan.ocr.raw, "lifelock"),
132                          strings.icontains(.scan.ocr.raw, "best buy"),
133                          strings.icontains(.scan.ocr.raw, "mcafee"),
134                          strings.icontains(.scan.ocr.raw, "norton"),
135                          strings.icontains(.scan.ocr.raw, "ebay"),
136                          strings.icontains(.scan.ocr.raw, "paypal"),
137                        )
138                      )
139                  )
140                  or any(ml.logo_detect(.).brands,
141                         .name in ("PayPal", "Norton", "GeekSquad", "Ebay")
142                  )
143                )
144              )
145      )
146    )
147  )  
148attack_types:
149  - "Callback Phishing"
150tactics_and_techniques:
151  - "Evasion"
152  - "Free email provider"
153  - "Impersonation: Brand"
154  - "Social engineering"
155detection_methods:
156  - "Computer Vision"
157  - "Content analysis"
158  - "Header analysis"
159  - "Optical Character Recognition"
160id: "f2fe1294-ca43-5290-84fd-02f8149c5de7"
to-top