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 any(filter(beta.html_xpath(body.html,
 21                                 // 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.
 22                                 // using //text()[normalize-space()] allows us to split each table up by line breaks, so each line can be inspected uniquely 
 23                                 '//img[@alt="PayPal"]/following::table[not(descendant::table) and count(following::hr[@class="footerDivider"]) > 0]//text()[normalize-space()]'
 24                 ).nodes,
 25                 (
 26                   // icontains a phone number
 27                   (
 28                     regex.icontains(strings.replace_confusables(.display_text),
 29                                     '\b\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\b'
 30                     )
 31                     or regex.icontains(strings.replace_confusables(.display_text),
 32                                        '\+[ilo0-9]{1,3}[ilo0-9]{10}'
 33                     )
 34                     or // +12028001238
 35   regex.icontains(strings.replace_confusables(.display_text),
 36                   '[ilo0-9]{3}\.[ilo0-9]{3}\.[ilo0-9]{4}'
 37                     )
 38                     or // 202-800-1238
 39   regex.icontains(strings.replace_confusables(.display_text),
 40                   '[ilo0-9]{3}-[ilo0-9]{3}-[ilo0-9]{4}'
 41                     )
 42                     or // (202) 800-1238
 43   regex.icontains(strings.replace_confusables(.display_text),
 44                   '\([ilo0-9]{3}\)\s[ilo0-9]{3}-[ilo0-9]{4}'
 45                     )
 46                     or // (202)-800-1238
 47   regex.icontains(strings.replace_confusables(.display_text),
 48                   '\([ilo0-9]{3}\)-[ilo0-9]{3}-[ilo0-9]{4}'
 49                     )
 50                     or ( // 8123456789
 51                       regex.icontains(strings.replace_confusables(.display_text),
 52                                       '8[ilo0-9]{9}'
 53                       )
 54                       and regex.icontains(strings.replace_confusables(.display_text
 55                                           ),
 56                                           '\+[1l]'
 57                       )
 58                     )
 59                   )
 60                 )
 61                 // filter out elements which contain non actor controlled details
 62                 // this often wording from paypal templates that might contain phone numbers
 63                 // but are not elements that are actor controlled. 
 64  
 65                 // main customer service number
 66                 and not strings.icontains(.display_text, '888-221-1161')
 67                 // credit services number
 68                 and not strings.icontains(.display_text, '844-896-4937')
 69                 // pay in 4 number
 70                 and not strings.icontains(.display_text, '(800) 504-7534')
 71                 // debt collections for PayPal
 72                 and not strings.icontains(.display_text, '866-380-1798')
 73                 // often the transcation id looks like a phone number and matches the regex
 74                 and not regex.icontains(.display_text, "Transaction (date|ID)\n")
 75                 // this segment can include phone numbers, but the wording is not actor controlled and shows up "under the fold" in the templates
 76                 and not strings.istarts_with(.display_text, "If you have any questions about this payment, you can")
 77          ),
 78          strings.icontains(.display_text, "you did not")
 79          or strings.icontains(.display_text, "Critical Alert")
 80          or strings.icontains(.display_text, "is not for")
 81          or strings.icontains(.display_text, "done by you")
 82          or regex.icontains(.display_text, "don['’]t recognize")
 83          or regex.icontains(.display_text, "didn['’]t (?:ma[kd]e|place) this")
 84          or regex.icontains(.display_text, "[wh]as.*placed by you")
 85          or strings.icontains(.display_text, "issue with")
 86          or regex.icontains(.display_text, "was.*made by you")
 87          or (
 88            strings.icontains(.display_text, "Fraud")
 89            and strings.icontains(.display_text, "Alert")
 90          )
 91          or strings.icontains(.display_text, "fraudulent")
 92          or strings.icontains(.display_text, "using your PayPal")
 93          or strings.icontains(.display_text, "subscription")
 94          or strings.icontains(.display_text, "antivirus")
 95          or strings.icontains(.display_text, "support")
 96          or strings.icontains(.display_text, "sincerely apologize")
 97          or strings.icontains(.display_text, "receipt")
 98          // pull in common wording from transaction types from paypal
 99          // this wording should be part of the template and not actor controlled
100          // but is generally prepended or appended with actor controlled elements
101          // such as using the business name to deliver callback details
102          // when a phone number is present 
103          or strings.icontains(.display_text, "sent you an invoice")
104          or strings.icontains(.display_text, "a money request")
105          or strings.icontains(.display_text, "invited you as a developer")
106  
107          // 
108          or strings.icontains(.display_text, "Purchase")
109          or strings.icontains(.display_text, "Market*Value")
110          or strings.icontains(.display_text, "BTC")
111          or strings.icontains(.display_text, "Etherium (ETH)")
112          or strings.icontains(.display_text, "get in touch with our")
113          or strings.icontains(.display_text, "quickly inform")
114          or strings.icontains(.display_text, "quickly reach ")
115          or strings.icontains(.display_text, "detected unusual transactions")
116          or strings.icontains(.display_text, "without your authorization")
117          or strings.icontains(.display_text, "unauthorized activitiy")
118          or strings.icontains(.display_text, "unauthorized transaction")
119          or strings.icontains(.display_text, "cancel")
120          or strings.icontains(.display_text, "renew")
121          or strings.icontains(.display_text, "refund")
122          or regex.icontains(.display_text, 'help.{0,3}desk')
123          or strings.icontains(.display_text, " your funds")
124          or strings.icontains(.display_text, " your checking")
125          or strings.icontains(.display_text, " your saving")
126          or strings.icontains(.display_text, "secure your account")
127          or strings.icontains(.display_text, "recover your")
128          or strings.icontains(.display_text, "unusual activity")
129          or strings.icontains(.display_text, "suspicious transaction")
130          or strings.icontains(.display_text, "transaction history")
131          or strings.icontains(.display_text, "please ignore this")
132          or strings.icontains(.display_text, "will be approved")
133          or strings.icontains(.display_text, "report activity")
134  
135          // Unicode confusables words obfuscated in note
136          or regex.icontains(.display_text,
137                             '\+𝟭|𝗽𝗮𝘆𝗺𝗲𝗻𝘁|𝗛𝗲𝗹𝗽 𝗗𝗲𝘀𝗸|𝗿𝗲𝗳𝘂𝗻𝗱|𝗮𝗻𝘁𝗶𝘃𝗶𝗿𝘂𝘀|𝗰𝗮𝗹𝗹|𝗰𝗮𝗻𝗰𝗲𝗹|𝗰𝗼𝗻𝘁𝗮𝗰𝘁|cᴀʟʟ'
138          )
139          or strings.icontains(.display_text, "kindly")
140          or regex.icontains(strings.replace_confusables(.display_text),
141                             '(?:call|cᴀʟʟ|reach|contact|get in touch|\binform\b|let us know)'
142          )
143  )  
144attack_types:
145  - "BEC/Fraud"
146  - "Callback Phishing"
147tactics_and_techniques:
148  - "Evasion"
149  - "Social engineering"
150detection_methods:
151  - "Content analysis"
152  - "Header analysis"
153  - "Sender analysis"
154id: "0ff7a0d4-164d-5ff1-8765-783fa2008b0f"
to-top