BEC/Fraud: Job scam fake thread or plaintext pivot to freemail

Detects potential job scams using plaintext or fake threads attempting to pivot to a freemail address from an unsolicited sender.

Sublime rule (View on GitHub)

 1name: "BEC/Fraud: Job scam fake thread or plaintext pivot to freemail"
 2description: "Detects potential job scams using plaintext or fake threads attempting to pivot to a freemail address from an unsolicited sender."
 3type: "rule"
 4severity: "medium"
 5source: |
 6  type.inbound
 7  and any(ml.nlu_classifier(body.current_thread.text).entities,
 8          .name in ("greeting", "salutation")
 9  )
10  
11  // most likely to occur in plain text
12  and (
13    body.html.raw is null
14    or 
15  
16    // HTML is not null but fake thread
17    (
18      subject.is_reply or subject.is_forward
19    )
20    and (
21      (length(headers.references) == 0 and headers.in_reply_to is null)
22      or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
23    )
24  )
25  and (
26    3 of (
27      any([subject.subject, body.current_thread.text],
28          regex.icontains(., '(full|part).time')
29      ),
30      strings.ilike(body.current_thread.text, '*job*'),
31      regex.icontains(body.current_thread.text, '\bHR\b'),
32      strings.ilike(body.current_thread.text, '*manager*'),
33      strings.ilike(body.current_thread.text, '*commission*'),
34      strings.ilike(body.current_thread.text, '*hourly*'),
35      strings.ilike(body.current_thread.text, '*per hour*'),
36      strings.ilike(body.current_thread.text, '*prior experience*'),
37      strings.ilike(body.current_thread.text, '*company rep*'),
38      strings.ilike(body.current_thread.text, "100% legal")
39    )
40    or (
41      length(ml.nlu_classifier(body.current_thread.text).topics) == 1
42      and any(ml.nlu_classifier(body.current_thread.text).topics,
43              .name == "Professional and Career Development"
44              and .confidence == "high"
45      )
46      and (
47        length(recipients.to) == 0
48        or all(recipients.to,
49               strings.ilike(.display_name, "Undisclosed?recipients")
50        )
51      )
52    )
53  )
54  
55  // all attachments are images or there's no attachments
56  and (
57    (
58      length(attachments) > 0
59      and all(attachments, .file_type in $file_types_images)
60    )
61    or length(attachments) == 0
62  )
63  
64  // there's an email in the body and it's a freemail
65  and any(regex.extract(body.current_thread.text,
66                        "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
67          ),
68          strings.parse_email(.full_match).domain.domain in $free_email_providers
69          or strings.parse_email(.full_match).domain.root_domain in $free_email_providers
70  )
71  
72  // and that email doesn't match the sender domain
73  and (
74    all(body.links, .href_url.domain.root_domain != sender.email.domain.domain)
75    or sender.email.domain.root_domain in $free_email_providers
76  )
77  and (
78    (
79      not profile.by_sender().solicited
80      and not profile.by_sender().any_messages_benign
81    )
82    or profile.by_sender().any_messages_malicious_or_spam
83  )
84  and not profile.by_sender().any_messages_benign  
85attack_types:
86  - "BEC/Fraud"
87tactics_and_techniques:
88  - "Free email provider"
89  - "Out of band pivot"
90detection_methods:
91  - "Content analysis"
92  - "File analysis"
93  - "Natural Language Understanding"
94id: "ce21c151-90c2-5573-b19e-3dcbcfc0a195"
to-top