Callback phishing via Adobe Sign comment

This rule inspects messages originating from legitimate Adobe Sign infrastructure, with content matching Callback Phishing criteria, in the body, requiring at least one brand name, as well as 3 matching Callback Phishing terms and a phone number.

Sublime rule (View on GitHub)

  1name: "Callback phishing via Adobe Sign comment"
  2description: |
  3    This rule inspects messages originating from legitimate Adobe Sign infrastructure, with content matching Callback Phishing criteria, in the body, requiring at least one brand name, as well as 3 matching Callback Phishing terms and a phone number. 
  4type: "rule"
  5severity: "high"
  6source: |
  7  type.inbound
  8  and length(attachments) == 0
  9
 10  // Legitimate Docusign sending infratructure
 11  and sender.email.domain.root_domain == 'adobesign.com'
 12  and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
 13  and (
 14    // this section is synced with attachment_callback_phish_with_pdf.yml and attachment_callback_phish_with_img.yml
 15    regex.icontains(strings.replace_confusables(body.current_thread.text),
 16                    '(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
 17    )
 18    or any(ml.logo_detect(file.message_screenshot()).brands,
 19           .name in ("PayPal", "Norton", "GeekSquad", "Ebay", "McAfee", "AT&T")
 20    )
 21  )
 22  and (
 23    (
 24      // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
 25      // however, the 3 of logic and requiring a phone number is specific to this rule in order to reduce FPs
 26      // caused by messages which mention cancelling or otherwise managing a subscription
 27      // it is also synced and below for message_screenshot OCR output
 28      3 of (
 29        strings.icontains(body.current_thread.text, 'purchase'),
 30        strings.icontains(body.current_thread.text, 'payment'),
 31        strings.icontains(body.current_thread.text, 'transaction'),
 32        strings.icontains(body.current_thread.text, 'subscription'),
 33        strings.icontains(body.current_thread.text, 'antivirus'),
 34        strings.icontains(body.current_thread.text, 'order'),
 35        strings.icontains(body.current_thread.text, 'support'),
 36        strings.icontains(body.current_thread.text, 'help line'),
 37        strings.icontains(body.current_thread.text, 'receipt'),
 38        strings.icontains(body.current_thread.text, 'invoice'),
 39        strings.icontains(body.current_thread.text, 'call'),
 40        strings.icontains(body.current_thread.text, 'cancel'),
 41        strings.icontains(body.current_thread.text, 'renew'),
 42        strings.icontains(body.current_thread.text, 'refund'),
 43        regex.icontains(body.current_thread.text, "(?:reach|contact) us at"),
 44        strings.icontains(body.current_thread.text, "+1"),
 45        strings.icontains(body.current_thread.text, "amount"),
 46        strings.icontains(body.current_thread.text, "charged"),
 47        strings.icontains(body.current_thread.text, "crypto"),
 48        strings.icontains(body.current_thread.text, "wallet address"),
 49        regex.icontains(body.current_thread.text, '\$\d{3}\.\d{2}\b'),
 50      )
 51      // phone number regex
 52      and regex.icontains(body.current_thread.text,
 53                          '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
 54                          '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
 55      )
 56    )
 57    or (
 58      // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
 59      // and above for current_thread.text
 60      //
 61      // This rule makes use of a beta feature and is subject to change without notice
 62      // using the beta feature in custom rules is not suggested until it has been formally released
 63      //
 64      3 of (
 65        strings.icontains(beta.ocr(file.message_screenshot()).text, 'purchase'),
 66        strings.icontains(beta.ocr(file.message_screenshot()).text, 'payment'),
 67        strings.icontains(beta.ocr(file.message_screenshot()).text, 'transaction'),
 68        strings.icontains(beta.ocr(file.message_screenshot()).text,
 69                          'subscription'
 70        ),
 71        strings.icontains(beta.ocr(file.message_screenshot()).text, 'antivirus'),
 72        strings.icontains(beta.ocr(file.message_screenshot()).text, 'order'),
 73        strings.icontains(beta.ocr(file.message_screenshot()).text, 'support'),
 74        strings.icontains(beta.ocr(file.message_screenshot()).text, 'help line'),
 75        strings.icontains(beta.ocr(file.message_screenshot()).text, 'receipt'),
 76        strings.icontains(beta.ocr(file.message_screenshot()).text, 'invoice'),
 77        strings.icontains(beta.ocr(file.message_screenshot()).text, 'call'),
 78        strings.icontains(beta.ocr(file.message_screenshot()).text, 'helpdesk'),
 79        strings.icontains(beta.ocr(file.message_screenshot()).text, 'cancel'),
 80        strings.icontains(beta.ocr(file.message_screenshot()).text, 'renew'),
 81        strings.icontains(beta.ocr(file.message_screenshot()).text, 'refund'),
 82        regex.icontains(beta.ocr(file.message_screenshot()).text,
 83                        "(?:reach|contact) us at"
 84        ),
 85        strings.icontains(beta.ocr(file.message_screenshot()).text, '+1'),
 86        strings.icontains(beta.ocr(file.message_screenshot()).text, 'amount'),
 87        strings.icontains(beta.ocr(file.message_screenshot()).text, 'charged'),
 88        strings.icontains(beta.ocr(file.message_screenshot()).text, 'crypto'),
 89        strings.icontains(beta.ocr(file.message_screenshot()).text,
 90                          'wallet address'
 91        ),
 92        regex.icontains(beta.ocr(file.message_screenshot()).text,
 93                        '\$\d{3}\.\d{2}\b'
 94        ),
 95      )
 96      // phone number regex
 97      and regex.icontains(beta.ocr(file.message_screenshot()).text,
 98                          '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
 99                          '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
100      )
101  
102      // negate messages with previous threads.  While callback phishing with thread hijacking or with current_thread 
103      // padded with whitespace and previous threads in the message has been observed, the intetion of using OCR is for image embedded callbacks
104      and not regex.icount(beta.ocr(file.message_screenshot()).text,
105                           '(?:from|to|sent|date|cc|subject):'
106      ) > 3
107      // this notation of previous threads often only occurs once
108      and not regex.icontains(beta.ocr(file.message_screenshot()).text,
109                              'wrote:[\r\n]'
110      )
111    )
112  )  
113attack_types:
114  - "Callback Phishing"
115tactics_and_techniques:
116  - "Evasion"
117  - "Impersonation: Brand"
118  - "Out of band pivot"
119  - "Social engineering"
120detection_methods:
121  - "Content analysis"
122  - "Computer Vision"
123  - "Header analysis"
124  - "Sender analysis"
125  - "URL analysis"
126id: "7eb4516d-f358-5c22-b527-34db0a532df9"
to-top