Detection rules โ€บ Sublime MQL

PayPal invoice abuse

Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

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.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesBEC/Fraud, Callback Phishing
Tactics and techniquesEvasion, Social engineering

Event coverage

Rule body MQL

type.inbound
and length(attachments) == 0
and sender.email.domain.root_domain in (
  "paypal.com",
  "paypal.com.mx",
  "paypal.com.br",
  "paypal.com.ar",
  "paypal.co.uk"
)
and (
  any(filter(html.xpath(body.html,
                        // 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.
                        // using //text()[normalize-space()] allows us to split each table up by line breaks, so each line can be inspected uniquely
                        '//img[@alt="PayPal"]/following::table[not(descendant::table) and count(following::hr[@class="footerDivider"]) > 0]//text()[normalize-space()]'
             ).nodes,
             (
               // icontains a phone number
               (
                 regex.icontains(strings.replace_confusables(.display_text),
                                 '\b\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\b'
                 )
                 or regex.icontains(strings.replace_confusables(.display_text),
                                    '\+[ilo0-9]{1,3}[ilo0-9]{10}'
                 )
                 // +12028001238
                 or regex.icontains(strings.replace_confusables(.display_text),
                                    '[ilo0-9]{3}\.[ilo0-9]{3}\.[ilo0-9]{4}'
                 )
                 // 202-800-1238
                 or regex.icontains(strings.replace_confusables(.display_text),
                                    '[ilo0-9]{3}-[ilo0-9]{3}-[ilo0-9]{4}'
                 )
                 // (202) 800-1238
                 // (202) -800 -1238
                 // (202) 800 1238
                 // (202)-800-1238
                 or regex.icontains(strings.replace_confusables(.display_text),
                                    '\([ilo0-9]{3}\)[\s-]+[ilo0-9]{3}[\s-]+[ilo0-9]{4}'
                 )
                 // (202)-800-1238
                 or regex.icontains(strings.replace_confusables(.display_text),
                                    '\([ilo0-9]{3}\)-[ilo0-9]{3}-[ilo0-9]{4}'
                 )
                 or ( // 8123456789
                   regex.icontains(strings.replace_confusables(.display_text),
                                   '8[ilo0-9]{9}'
                   )
                   and regex.icontains(strings.replace_confusables(.display_text
                                       ),
                                       '\+[1l]'
                   )
                 )
               )
             )
             // filter out elements which contain non actor controlled details
             // this often wording from paypal templates that might contain phone numbers
             // but are not elements that are actor controlled.

             // main customer service number
             and not strings.icontains(.display_text, '888-221-1161')
             // credit services number
             and not strings.icontains(.display_text, '844-896-4937')
             // pay in 4 number
             and not strings.icontains(.display_text, '(800) 504-7534')
             // debt collection for pay later
             and not strings.icontains(.display_text, '877-589-5171')
             // debt collections for PayPal
             and not strings.icontains(.display_text, '866-380-1798')
             // card activation
             and not strings.icontains(.display_text, '800-314-8298')
             // often the transcation id looks like a phone number and matches the regex
             and not regex.icontains(.display_text, "Transaction (date|ID)\n")
             // this segment can include phone numbers, but the wording is not actor controlled and shows up "under the fold" in the templates
             and not strings.istarts_with(.display_text,
                                          "If you have any questions about this payment, you can"
             )
      ),
      strings.icontains(.display_text, "you did not")
      or strings.icontains(.display_text, "Critical Alert")
      or strings.icontains(.display_text, "is not for")
      or strings.icontains(.display_text, "done by you")
      or regex.icontains(.display_text, "don['โ€™]t recognize")
      or regex.icontains(.display_text, "didn['โ€™]t (?:ma[kd]e|place) this")
      or regex.icontains(.display_text, "[wh]as.*placed by you")
      or strings.icontains(.display_text, "issue with")
      or regex.icontains(.display_text, "was.*made by you")
      or (
        strings.icontains(.display_text, "Fraud")
        and strings.icontains(.display_text, "Alert")
      )
      or strings.icontains(.display_text, "fraudulent")
      or strings.icontains(.display_text, "using your PayPal")
      or strings.icontains(.display_text, "subscription")
      or strings.icontains(.display_text, "antivirus")
      or strings.icontains(.display_text, "support")
      or strings.icontains(.display_text, "sincerely apologize")
      or strings.icontains(.display_text, "receipt")
      // pull in common wording from transaction types from paypal
      // this wording should be part of the template and not actor controlled
      // but is generally prepended or appended with actor controlled elements
      // such as using the business name to deliver callback details
      // when a phone number is present
      or strings.icontains(.display_text, "sent you an invoice")
      or strings.icontains(.display_text, "a money request")
      or strings.icontains(.display_text, "invited you as a developer")
      or strings.icontains(.display_text, "Purchase")
      or strings.icontains(.display_text, "Market*Value")
      or strings.icontains(.display_text, "BTC")
      or strings.icontains(.display_text, "Etherium (ETH)")
      or strings.icontains(.display_text, "get in touch with our")
      or strings.icontains(.display_text, "quickly inform")
      or strings.icontains(.display_text, "quickly reach ")
      or strings.icontains(.display_text, "detected unusual transactions")
      or strings.icontains(.display_text, "without your authorization")
      or strings.icontains(.display_text, "unauthorized activitiy")
      or strings.icontains(.display_text, "unauthorized transaction")
      or strings.icontains(.display_text, "cancel")
      or strings.icontains(.display_text, "renew")
      or strings.icontains(.display_text, "refund")
      or regex.icontains(.display_text, 'help.{0,3}desk')
      or strings.icontains(.display_text, " your funds")
      or strings.icontains(.display_text, " your checking")
      or strings.icontains(.display_text, " your saving")
      or strings.icontains(.display_text, "secure your account")
      or strings.icontains(.display_text, "recover your")
      or strings.icontains(.display_text, "unusual activity")
      or strings.icontains(.display_text, "suspicious transaction")
      or strings.icontains(.display_text, "transaction history")
      or strings.icontains(.display_text, "please ignore this")
      or strings.icontains(.display_text, "will be approved")
      or strings.icontains(.display_text, "report activity")
      or strings.icontains(.display_text, "paypal billing team")

      // Unicode confusables words obfuscated in note
      or regex.icontains(.display_text,
                         '\+๐Ÿญ|๐—ฝ๐—ฎ๐˜†๐—บ๐—ฒ๐—ป๐˜|๐—›๐—ฒ๐—น๐—ฝ ๐——๐—ฒ๐˜€๐—ธ|๐—ฟ๐—ฒ๐—ณ๐˜‚๐—ป๐—ฑ|๐—ฎ๐—ป๐˜๐—ถ๐˜ƒ๐—ถ๐—ฟ๐˜‚๐˜€|๐—ฐ๐—ฎ๐—น๐—น|๐—ฐ๐—ฎ๐—ป๐—ฐ๐—ฒ๐—น|๐—ฐ๐—ผ๐—ป๐˜๐—ฎ๐—ฐ๐˜|cแด€สŸสŸ'
      )
      or strings.icontains(.display_text, "kindly")
      or regex.icontains(strings.replace_confusables(.display_text),
                         '(?:call|cแด€สŸสŸ|reach|contact|get in touch|\binform\b|let us know|coษดแด›แด€cแด›)'
      )
  )
  // message contains phone number regex and dollar ammounts in the subject
  or (
    regex.icontains(strings.replace_confusables(subject.base),
                    '\+?(?:[ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
                    '\+?(?:[ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-โ‹…]{0,5}[ilo0-9]{3}[\s\.\-โ‹…]{0,5}[ilo0-9]{4}'
    )
    and (
      regex.icontains(subject.base, '(?:USD|\$)\s?\d')
      or regex.icontains(subject.base, '\d+\.\d{2}\s?(?:USD|usd)')
    )
  )
)
// 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
and not (
  strings.icontains(body.html.display_text, "settlement")
  and (
    strings.icontains(body.html.display_text, "court")
    or strings.icontains(body.html.display_text, "FTC")
    or strings.icontains(body.html.display_text, "administrator")
  )
)

Detection logic

Scope: inbound message.

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.

  1. inbound message
  2. length(attachments) is 0
  3. sender.email.domain.root_domain in ('paypal.com', 'paypal.com.mx', 'paypal.com.br', 'paypal.com.ar', 'paypal.co.uk')
  4. any of:
    • any of filter(...) where any holds:
      • .display_text contains 'you did not'
      • .display_text contains 'Critical Alert'
      • .display_text contains 'is not for'
      • .display_text contains 'done by you'
      • .display_text matches "don['โ€™]t recognize"
      • .display_text matches "didn['โ€™]t (?:ma[kd]e|place) this"
      • .display_text matches '[wh]as.*placed by you'
      • .display_text contains 'issue with'
      • .display_text matches 'was.*made by you'
      • all of:
        • .display_text contains 'Fraud'
        • .display_text contains 'Alert'
      • .display_text contains 'fraudulent'
      • .display_text contains 'using your PayPal'
      • .display_text contains 'subscription'
      • .display_text contains 'antivirus'
      • .display_text contains 'support'
      • .display_text contains 'sincerely apologize'
      • .display_text contains 'receipt'
      • .display_text contains 'sent you an invoice'
      • .display_text contains 'a money request'
      • .display_text contains 'invited you as a developer'
      • .display_text contains 'Purchase'
      • .display_text contains 'Market*Value'
      • .display_text contains 'BTC'
      • .display_text contains 'Etherium (ETH)'
      • .display_text contains 'get in touch with our'
      • .display_text contains 'quickly inform'
      • .display_text contains 'quickly reach '
      • .display_text contains 'detected unusual transactions'
      • .display_text contains 'without your authorization'
      • .display_text contains 'unauthorized activitiy'
      • .display_text contains 'unauthorized transaction'
      • .display_text contains 'cancel'
      • .display_text contains 'renew'
      • .display_text contains 'refund'
      • .display_text matches 'help.{0,3}desk'
      • .display_text contains ' your funds'
      • .display_text contains ' your checking'
      • .display_text contains ' your saving'
      • .display_text contains 'secure your account'
      • .display_text contains 'recover your'
      • .display_text contains 'unusual activity'
      • .display_text contains 'suspicious transaction'
      • .display_text contains 'transaction history'
      • .display_text contains 'please ignore this'
      • .display_text contains 'will be approved'
      • .display_text contains 'report activity'
      • .display_text contains 'paypal billing team'
      • .display_text matches '\\+๐Ÿญ|๐—ฝ๐—ฎ๐˜†๐—บ๐—ฒ๐—ป๐˜|๐—›๐—ฒ๐—น๐—ฝ ๐——๐—ฒ๐˜€๐—ธ|๐—ฟ๐—ฒ๐—ณ๐˜‚๐—ป๐—ฑ|๐—ฎ๐—ป๐˜๐—ถ๐˜ƒ๐—ถ๐—ฟ๐˜‚๐˜€|๐—ฐ๐—ฎ๐—น๐—น|๐—ฐ๐—ฎ๐—ป๐—ฐ๐—ฒ๐—น|๐—ฐ๐—ผ๐—ป๐˜๐—ฎ๐—ฐ๐˜|cแด€สŸสŸ'
      • .display_text contains 'kindly'
      • strings.replace_confusables(.display_text) matches '(?:call|cแด€สŸสŸ|reach|contact|get in touch|\\binform\\b|let us know|coษดแด›แด€cแด›)'
    • all of:
      • strings.replace_confusables(subject.base) matches any of 2 patterns
        • \+?(?:[ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
        • \+?(?:[ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-โ‹…]{0,5}[ilo0-9]{3}[\s\.\-โ‹…]{0,5}[ilo0-9]{4}
      • any of:
        • subject.base matches '(?:USD|\\$)\\s?\\d'
        • subject.base matches '\\d+\\.\\d{2}\\s?(?:USD|usd)'
  5. not:
    • all of:
      • body.html.display_text contains 'settlement'
      • any of:
        • body.html.display_text contains 'court'
        • body.html.display_text contains 'FTC'
        • body.html.display_text contains 'administrator'

Inspects: body.html, body.html.display_text, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: html.xpath, regex.icontains, strings.icontains, strings.istarts_with, strings.replace_confusables.

Indicators matched (80)

FieldMatchValue
sender.email.domain.root_domainmemberpaypal.com
sender.email.domain.root_domainmemberpaypal.com.mx
sender.email.domain.root_domainmemberpaypal.com.br
sender.email.domain.root_domainmemberpaypal.com.ar
sender.email.domain.root_domainmemberpaypal.co.uk
regex.icontainsregex\b\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}\b
regex.icontainsregex\+[ilo0-9]{1,3}[ilo0-9]{10}
regex.icontainsregex[ilo0-9]{3}\.[ilo0-9]{3}\.[ilo0-9]{4}
regex.icontainsregex[ilo0-9]{3}-[ilo0-9]{3}-[ilo0-9]{4}
regex.icontainsregex\([ilo0-9]{3}\)[\s-]+[ilo0-9]{3}[\s-]+[ilo0-9]{4}
regex.icontainsregex\([ilo0-9]{3}\)-[ilo0-9]{3}-[ilo0-9]{4}
regex.icontainsregex8[ilo0-9]{9}
68 more
regex.icontainsregex\+[1l]
strings.icontainssubstring888-221-1161
strings.icontainssubstring844-896-4937
strings.icontainssubstring(800) 504-7534
strings.icontainssubstring877-589-5171
strings.icontainssubstring866-380-1798
strings.icontainssubstring800-314-8298
regex.icontainsregexTransaction (date|ID)\n
strings.istarts_withprefixIf you have any questions about this payment, you can
strings.icontainssubstringyou did not
strings.icontainssubstringCritical Alert
strings.icontainssubstringis not for
strings.icontainssubstringdone by you
regex.icontainsregexdon['โ€™]t recognize
regex.icontainsregexdidn['โ€™]t (?:ma[kd]e|place) this
regex.icontainsregex[wh]as.*placed by you
strings.icontainssubstringissue with
regex.icontainsregexwas.*made by you
strings.icontainssubstringFraud
strings.icontainssubstringAlert
strings.icontainssubstringfraudulent
strings.icontainssubstringusing your PayPal
strings.icontainssubstringsubscription
strings.icontainssubstringantivirus
strings.icontainssubstringsupport
strings.icontainssubstringsincerely apologize
strings.icontainssubstringreceipt
strings.icontainssubstringsent you an invoice
strings.icontainssubstringa money request
strings.icontainssubstringinvited you as a developer
strings.icontainssubstringPurchase
strings.icontainssubstringMarket*Value
strings.icontainssubstringBTC
strings.icontainssubstringEtherium (ETH)
strings.icontainssubstringget in touch with our
strings.icontainssubstringquickly inform
strings.icontainssubstringquickly reach
strings.icontainssubstringdetected unusual transactions
strings.icontainssubstringwithout your authorization
strings.icontainssubstringunauthorized activitiy
strings.icontainssubstringunauthorized transaction
strings.icontainssubstringcancel
strings.icontainssubstringrenew
strings.icontainssubstringrefund
regex.icontainsregexhelp.{0,3}desk
strings.icontainssubstring your funds
strings.icontainssubstring your checking
strings.icontainssubstring your saving
strings.icontainssubstringsecure your account
strings.icontainssubstringrecover your
strings.icontainssubstringunusual activity
strings.icontainssubstringsuspicious transaction
strings.icontainssubstringtransaction history
strings.icontainssubstringplease ignore this
strings.icontainssubstringwill be approved
strings.icontainssubstringreport activity
strings.icontainssubstringpaypal billing team
regex.icontainsregex\+๐Ÿญ|๐—ฝ๐—ฎ๐˜†๐—บ๐—ฒ๐—ป๐˜|๐—›๐—ฒ๐—น๐—ฝ ๐——๐—ฒ๐˜€๐—ธ|๐—ฟ๐—ฒ๐—ณ๐˜‚๐—ป๐—ฑ|๐—ฎ๐—ป๐˜๐—ถ๐˜ƒ๐—ถ๐—ฟ๐˜‚๐˜€|๐—ฐ๐—ฎ๐—น๐—น|๐—ฐ๐—ฎ๐—ป๐—ฐ๐—ฒ๐—น|๐—ฐ๐—ผ๐—ป๐˜๐—ฎ๐—ฐ๐˜|cแด€สŸสŸ
strings.icontainssubstringkindly
regex.icontainsregex(?:call|cแด€สŸสŸ|reach|contact|get in touch|\binform\b|let us know|coษดแด›แด€cแด›)
regex.icontainsregex\+?(?:[ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
regex.icontainsregex\+?(?:[ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-โ‹…]{0,5}[ilo0-9]{3}[\s\.\-โ‹…]{0,5}[ilo0-9]{4}
regex.icontainsregex(?:USD|\$)\s?\d
regex.icontainsregex\d+\.\d{2}\s?(?:USD|usd)
strings.icontainssubstringsettlement
strings.icontainssubstringcourt
strings.icontainssubstringFTC
strings.icontainssubstringadministrator