PayPal invoice abuse

A fraudulent invoice/receipt found in the body of the message sent by exploiting Paypal's invoicing service. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.

Sublime rule (View on GitHub)

  1name: "PayPal invoice abuse"
  2description: |
  3  A fraudulent invoice/receipt found in the body of the message sent by exploiting Paypal's invoicing service.
  4  Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. 
  5  The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.  
  6type: "rule"
  7references:
  8  - "https://anderegg.ca/2023/02/01/a-novel-paypal-scam"
  9severity: "medium"
 10source: |
 11  type.inbound
 12  and length(attachments) == 0
 13  and sender.email.domain.root_domain in (
 14    "paypal.com",
 15    "paypal.com.mx",
 16    "paypal.com.br",
 17    "paypal.com.ar",
 18    "paypal.co.uk"
 19  )
 20  and (
 21    any(filter(html.xpath(body.html,
 22                          // all the tables, which don't have descendant tables, after the first image and before a hr with a footerDivider class that appears after the current table.
 23                          // using //text()[normalize-space()] allows us to split each table up by line breaks, so each line can be inspected uniquely
 24                          '//img[@alt="PayPal"]/following::table[not(descendant::table) and count(following::hr[@class="footerDivider"]) > 0]//text()[normalize-space()]'
 25               ).nodes,
 26               (
 27                 // icontains a phone number
 28                 (
 29                   regex.icontains(strings.replace_confusables(.display_text),
 30                                   '\b\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\b'
 31                   )
 32                   or regex.icontains(strings.replace_confusables(.display_text),
 33                                      '\+[ilo0-9]{1,3}[ilo0-9]{10}'
 34                   )
 35                   // +12028001238
 36                   or regex.icontains(strings.replace_confusables(.display_text),
 37                                      '[ilo0-9]{3}\.[ilo0-9]{3}\.[ilo0-9]{4}'
 38                   )
 39                   // 202-800-1238
 40                   or regex.icontains(strings.replace_confusables(.display_text),
 41                                      '[ilo0-9]{3}-[ilo0-9]{3}-[ilo0-9]{4}'
 42                   )
 43                   // (202) 800-1238
 44                   // (202) -800 -1238
 45                   // (202) 800 1238
 46                   // (202)-800-1238
 47                   or regex.icontains(strings.replace_confusables(.display_text),
 48                                      '\([ilo0-9]{3}\)[\s-]+[ilo0-9]{3}[\s-]+[ilo0-9]{4}'
 49                   )
 50                   // (202)-800-1238
 51                   or regex.icontains(strings.replace_confusables(.display_text),
 52                                      '\([ilo0-9]{3}\)-[ilo0-9]{3}-[ilo0-9]{4}'
 53                   )
 54                   or ( // 8123456789
 55                     regex.icontains(strings.replace_confusables(.display_text),
 56                                     '8[ilo0-9]{9}'
 57                     )
 58                     and regex.icontains(strings.replace_confusables(.display_text
 59                                         ),
 60                                         '\+[1l]'
 61                     )
 62                   )
 63                 )
 64               )
 65               // filter out elements which contain non actor controlled details
 66               // this often wording from paypal templates that might contain phone numbers
 67               // but are not elements that are actor controlled.
 68  
 69               // main customer service number
 70               and not strings.icontains(.display_text, '888-221-1161')
 71               // credit services number
 72               and not strings.icontains(.display_text, '844-896-4937')
 73               // pay in 4 number
 74               and not strings.icontains(.display_text, '(800) 504-7534')
 75               // debt collection for pay later
 76               and not strings.icontains(.display_text, '877-589-5171')
 77               // debt collections for PayPal
 78               and not strings.icontains(.display_text, '866-380-1798')
 79               // card activation
 80               and not strings.icontains(.display_text, '800-314-8298')
 81               // often the transcation id looks like a phone number and matches the regex
 82               and not regex.icontains(.display_text, "Transaction (date|ID)\n")
 83               // this segment can include phone numbers, but the wording is not actor controlled and shows up "under the fold" in the templates
 84               and not strings.istarts_with(.display_text,
 85                                            "If you have any questions about this payment, you can"
 86               )
 87        ),
 88        strings.icontains(.display_text, "you did not")
 89        or strings.icontains(.display_text, "Critical Alert")
 90        or strings.icontains(.display_text, "is not for")
 91        or strings.icontains(.display_text, "done by you")
 92        or regex.icontains(.display_text, "don['’]t recognize")
 93        or regex.icontains(.display_text, "didn['’]t (?:ma[kd]e|place) this")
 94        or regex.icontains(.display_text, "[wh]as.*placed by you")
 95        or strings.icontains(.display_text, "issue with")
 96        or regex.icontains(.display_text, "was.*made by you")
 97        or (
 98          strings.icontains(.display_text, "Fraud")
 99          and strings.icontains(.display_text, "Alert")
100        )
101        or strings.icontains(.display_text, "fraudulent")
102        or strings.icontains(.display_text, "using your PayPal")
103        or strings.icontains(.display_text, "subscription")
104        or strings.icontains(.display_text, "antivirus")
105        or strings.icontains(.display_text, "support")
106        or strings.icontains(.display_text, "sincerely apologize")
107        or strings.icontains(.display_text, "receipt")
108        // pull in common wording from transaction types from paypal
109        // this wording should be part of the template and not actor controlled
110        // but is generally prepended or appended with actor controlled elements
111        // such as using the business name to deliver callback details
112        // when a phone number is present
113        or strings.icontains(.display_text, "sent you an invoice")
114        or strings.icontains(.display_text, "a money request")
115        or strings.icontains(.display_text, "invited you as a developer")
116        or strings.icontains(.display_text, "Purchase")
117        or strings.icontains(.display_text, "Market*Value")
118        or strings.icontains(.display_text, "BTC")
119        or strings.icontains(.display_text, "Etherium (ETH)")
120        or strings.icontains(.display_text, "get in touch with our")
121        or strings.icontains(.display_text, "quickly inform")
122        or strings.icontains(.display_text, "quickly reach ")
123        or strings.icontains(.display_text, "detected unusual transactions")
124        or strings.icontains(.display_text, "without your authorization")
125        or strings.icontains(.display_text, "unauthorized activitiy")
126        or strings.icontains(.display_text, "unauthorized transaction")
127        or strings.icontains(.display_text, "cancel")
128        or strings.icontains(.display_text, "renew")
129        or strings.icontains(.display_text, "refund")
130        or regex.icontains(.display_text, 'help.{0,3}desk')
131        or strings.icontains(.display_text, " your funds")
132        or strings.icontains(.display_text, " your checking")
133        or strings.icontains(.display_text, " your saving")
134        or strings.icontains(.display_text, "secure your account")
135        or strings.icontains(.display_text, "recover your")
136        or strings.icontains(.display_text, "unusual activity")
137        or strings.icontains(.display_text, "suspicious transaction")
138        or strings.icontains(.display_text, "transaction history")
139        or strings.icontains(.display_text, "please ignore this")
140        or strings.icontains(.display_text, "will be approved")
141        or strings.icontains(.display_text, "report activity")
142        or strings.icontains(.display_text, "paypal billing team")
143  
144        // Unicode confusables words obfuscated in note
145        or regex.icontains(.display_text,
146                           '\+𝟭|𝗽𝗮𝘆𝗺𝗲𝗻𝘁|𝗛𝗲𝗹𝗽 𝗗𝗲𝘀𝗸|𝗿𝗲𝗳𝘂𝗻𝗱|𝗮𝗻𝘁𝗶𝘃𝗶𝗿𝘂𝘀|𝗰𝗮𝗹𝗹|𝗰𝗮𝗻𝗰𝗲𝗹|𝗰𝗼𝗻𝘁𝗮𝗰𝘁|cᴀʟʟ'
147        )
148        or strings.icontains(.display_text, "kindly")
149        or regex.icontains(strings.replace_confusables(.display_text),
150                           '(?:call|cᴀʟʟ|reach|contact|get in touch|\binform\b|let us know|coɴᴛᴀcᴛ)'
151        )
152    )
153    // message contains phone number regex and dollar ammounts in the subject
154    or (
155      regex.icontains(strings.replace_confusables(subject.base),
156                      '\+?(?:[ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
157                      '\+?(?:[ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
158      )
159      and (
160        regex.icontains(subject.base, '(?:USD|\$)\s?\d')
161        or regex.icontains(subject.base, '\d+\.\d{2}\s?(?:USD|usd)')
162      )
163    )
164  )
165  // Handle emails for class action settlement refunds. Not official PayPal communications but a common-enough thing where a small refund is sent from a court-appointed settlement administrator
166  and not (
167    strings.icontains(body.html.display_text, "settlement")
168    and (
169      strings.icontains(body.html.display_text, "court")
170      or strings.icontains(body.html.display_text, "FTC")
171      or strings.icontains(body.html.display_text, "administrator")
172    )
173  )  
174attack_types:
175  - "BEC/Fraud"
176  - "Callback Phishing"
177tactics_and_techniques:
178  - "Evasion"
179  - "Social engineering"
180detection_methods:
181  - "Content analysis"
182  - "Header analysis"
183  - "Sender analysis"
184id: "0ff7a0d4-164d-5ff1-8765-783fa2008b0f"
to-top