Attachment: PDF bid/proposal lure with credential theft indicators

Detects single-page PDF attachments containing bid, proposal, RFP, RFQ, or quotation-related lures combined with high-confidence credential theft language or suspicious domains. The rule examines various locations including PDF URLs, OCR content, file names, subject lines, and message body for these indicators.

Sublime rule (View on GitHub)

  1name: "Attachment: PDF bid/proposal lure with credential theft indicators"
  2description: "Detects single-page PDF attachments containing bid, proposal, RFP, RFQ, or quotation-related lures combined with high-confidence credential theft language or suspicious domains. The rule examines various locations including PDF URLs, OCR content, file names, subject lines, and message body for these indicators."
  3type: "rule"
  4severity: "medium"
  5source: |
  6  type.inbound
  7  // only one attachment
  8  and length(attachments) == 1
  9  // only pdfs with one page
 10  //
 11  // This rule makes use of a beta feature and is subject to change without notice
 12  // using the beta feature in custom rules is not suggested until it has been formally released
 13  //
 14  and any(attachments, .file_type == 'pdf' and beta.parse_exif(.).page_count == 1)
 15  // two of these...
 16  and 2 of (
 17    // bid/rfp/proposal phrases commonly observed in lures which are in the display text of a url from the pdf
 18    any(attachments,
 19        any(file.explode(.),
 20            any(.scan.url.urls,
 21                regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
 22                                '(?:\b(?:request|review)\b.{1,5}\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b)'
 23                )
 24            )
 25        )
 26    ),
 27    (
 28      // bid/rfp/proposal phrases commonly observed in lures which are in various spots in the message
 29      any([subject.base, sender.display_name, body.current_thread.text],
 30          regex.icontains(., '\b(?:bid|proposal|rfp|rfq|quotation)\b')
 31      )
 32    ),
 33    // bid/rfp/proposal phrases commonly observed in lures which are in the file name
 34    any(attachments,
 35        regex.icontains(.file_name, '\b(?:bid|proposal|rfp|rfq|quotation)\b')
 36    ),
 37    any(attachments,
 38        any(file.explode(.),
 39            // bid/rfp/proposal phrases commonly observed in lures which are in the ocr of the pdf
 40            regex.icontains(.scan.ocr.raw,
 41                            '(?:\b(?:request|review)\b.{1,5}\\b(?:bid|proposal|rfp|rfq|quotation)\b|\b(?:bid|proposal|rfp|rfq|quotation)\b.{1,5}\b(?:request|review)\b)'
 42            )
 43        )
 44    ),
 45    (
 46      any(attachments,
 47          any(file.explode(.),
 48              any(.scan.url.urls,
 49                  // bid/rfp/proposal phrases commonly observed in lures which are in the url
 50                  regex.icontains(.url,
 51                                  '(?:bid|proposal|agreement|contract|settlement|RFQ|RFP|quotation)'
 52                  )
 53              )
 54          )
 55      )
 56    )
 57  )
 58  
 59  // ocr indicates high confidence cred theft
 60  and (
 61    any(attachments,
 62        any(file.explode(.),
 63            any(ml.nlu_classifier(.scan.ocr.raw).intents,
 64                .name == 'cred_theft' and .confidence == 'high'
 65            )
 66            or any(ml.nlu_classifier(.scan.ocr.raw).topics,
 67                   .name == 'Purchase Orders' and .confidence == 'high'
 68            )
 69        )
 70    )
 71    // message body current thread indicates high confidence cred theft
 72    or any(ml.nlu_classifier(body.current_thread.text).intents,
 73           .name == 'cred_theft' and .confidence == 'high'
 74    )
 75    // message body current thread indicates high confidence cred theft
 76    or any(ml.nlu_classifier(body.current_thread.text).topics,
 77           .name == 'Purchase Orders' and .confidence == 'high'
 78    )
 79  )
 80  
 81  // pdf contains some suspicious url domain
 82  and (
 83    any(attachments,
 84        any(file.explode(.),
 85            any(.scan.url.urls,
 86                .domain.root_domain in $self_service_creation_platform_domains
 87                or .domain.domain in $self_service_creation_platform_domains
 88                or .domain.root_domain in $free_file_hosts
 89                or .domain.domain in $free_file_hosts
 90                or .domain.root_domain in $free_subdomain_hosts
 91                or .domain.domain in $free_subdomain_hosts
 92                or .domain.tld in $suspicious_tlds
 93                or .domain.domain in $url_shorteners
 94                or .domain.root_domain in $url_shorteners
 95            )
 96        )
 97    )
 98  )
 99  // we dont want emails where all the links are docusign or dotloop
100  and not all(body.links,
101              .href_url.domain.root_domain in (
102                'docusign.net',
103                'docusign.com',
104                'dotloop.com'
105              )
106  )
107  // negating solicited senders is necessary due to the nature of the rule
108  and not profile.by_sender().solicited
109  
110  // negate workflow robot
111  and not (
112    sender.email.local_part == 'workflow.robot'
113    and sender.email.domain.root_domain == 'effem.com'
114  )  
115attack_types:
116  - "BEC/Fraud"
117  - "Credential Phishing"
118tactics_and_techniques:
119  - "PDF"
120  - "Social engineering"
121  - "Free file host"
122  - "Free subdomain host"
123detection_methods:
124  - "File analysis"
125  - "Content analysis"
126  - "Optical Character Recognition"
127  - "Natural Language Understanding"
128  - "URL analysis"
129  - "Exif analysis"
130id: "7944c428-b0de-5641-9e71-c1590f1c71e5"
to-top