Attachment: Encrypted PDF with credential theft language in EML

Attached PDF is encrypted, and email body contains credential theft language, wrapped in an attached .eml file. Seen in-the-wild impersonating e-fax services.

Sublime rule (View on GitHub)

 1name: "Attachment: Encrypted PDF with credential theft language in EML"
 2description: "Attached PDF is encrypted, and email body contains credential theft language, wrapped in an attached .eml file. Seen in-the-wild impersonating e-fax services."
 3type: "rule"
 4severity: "medium"
 5source: |
 6  type.inbound
 7  and any(attachments,
 8          any(filter(file.parse_eml(.).attachments, .file_type == "pdf"),
 9              any(file.explode(.),
10                  any(.scan.exiftool.fields, .key == "Encryption")
11                  or (
12                    .scan.entropy.entropy > 7
13                    and any(.scan.strings.strings,
14                            strings.icontains(., "/Encrypt")
15                    )
16                  )
17              )
18              // Encrypted PDFs do not have child nodes with any data
19              and all(filter(file.explode(.), .depth > 0), .size == 0)
20          )
21          and (
22            any(ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intents,
23                .name == "cred_theft" and .confidence in ("medium", "high")
24            )
25            or any(ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(.
26                                                                   ).body.html
27                                              )
28                                     ).text
29                   ).intents,
30                   .name == "cred_theft" and .confidence in ("medium", "high")
31            )
32            or regex.icontains(file.parse_eml(.).body.current_thread.text,
33                               'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
34                               '(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
35                               'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
36                               '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
37            )
38            or (
39              (
40                length(file.parse_eml(.).body.current_thread.text) <= 10
41                or (file.parse_eml(.).body.current_thread.text is null)
42              )
43              and any(file.parse_eml(.).body.previous_threads,
44                      regex.icontains(.text,
45                                      'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
46                                      '(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
47                                      'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
48                                      '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
49                      )
50              )
51            )
52          )
53  )
54  // not forwards/replies
55  and not (
56    (length(headers.references) > 0 or headers.in_reply_to is not null)
57    and (subject.is_forward or subject.is_reply)
58    and length(body.previous_threads) >= 1
59  )
60  and (
61    (
62      profile.by_sender_email().prevalence in ("new", "outlier")
63      and not profile.by_sender_email().solicited
64    )
65    or (
66      profile.by_sender_email().any_messages_malicious_or_spam
67      and not profile.by_sender_email().any_messages_benign
68    )
69    or (
70      length(recipients.to) == 0
71      or (
72        all(recipients.to, .email.domain.valid == false)
73        and all(recipients.cc, .email.domain.valid == false)
74      )
75    )
76    or (
77      length(recipients.to) == 1
78      and any(recipients.to, .email.email == sender.email.email)
79    )
80  )
81  // negate highly trusted sender domains unless they fail DMARC authentication
82  and not (
83    sender.email.domain.root_domain in $high_trust_sender_root_domains
84    and coalesce(headers.auth_summary.dmarc.pass, false)
85  )  
86attack_types:
87  - "Credential Phishing"
88tactics_and_techniques:
89  - "Encryption"
90  - "Evasion"
91  - "PDF"
92  - "Social engineering"
93detection_methods:
94  - "Content analysis"
95  - "Exif analysis"
96  - "File analysis"
97  - "Natural Language Understanding"
98  - "Sender analysis"
99id: "f4a5fb9e-ecda-57a8-bc3c-851d64b8d06d"
to-top