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"