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              and (
 19                // Encrypted PDFs do not have child nodes with any data
 20                all(filter(file.explode(.), .depth > 0), .size == 0)
 21                // if we cracked the password, it will have child objects
 22                or (
 23                  any(file.explode(.), 'pdf_encryption_dict' in .flavors.yara)
 24                  and any(file.explode(.),
 25                          .scan.encrypted_pdf.cracked_password is not null
 26                  )
 27                )
 28              )
 29          )
 30          and (
 31            any(ml.nlu_classifier(file.parse_eml(.).body.current_thread.text).intents,
 32                .name == "cred_theft" and .confidence in ("medium", "high")
 33            )
 34            or any(ml.nlu_classifier(beta.ocr(file.html_screenshot(file.parse_eml(.
 35                                                                   ).body.html
 36                                              )
 37                                     ).text
 38                   ).intents,
 39                   .name == "cred_theft" and .confidence in ("medium", "high")
 40            )
 41            or regex.icontains(file.parse_eml(.).body.current_thread.text,
 42                               'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
 43                               '(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
 44                               'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
 45                               '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
 46            )
 47            or (
 48              (
 49                length(file.parse_eml(.).body.current_thread.text) <= 10
 50                or (file.parse_eml(.).body.current_thread.text is null)
 51              )
 52              and any(file.parse_eml(.).body.previous_threads,
 53                      regex.icontains(.text,
 54                                      'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
 55                                      '(?:Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
 56                                      'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
 57                                      '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}(?:PDF|statement)(?:\S+\s+){0,3}(?:pass(?:word|code)|\s*with\s+\S+)'
 58                      )
 59              )
 60            )
 61          )
 62  )
 63  // not forwards/replies
 64  and not (
 65    (length(headers.references) > 0 or headers.in_reply_to is not null)
 66    and (subject.is_forward or subject.is_reply)
 67    and length(body.previous_threads) >= 1
 68  )
 69  and (
 70    (
 71      profile.by_sender_email().prevalence in ("new", "outlier")
 72      and not profile.by_sender_email().solicited
 73    )
 74    or (
 75      profile.by_sender_email().any_messages_malicious_or_spam
 76      and not profile.by_sender_email().any_messages_benign
 77    )
 78    or (
 79      length(recipients.to) == 0
 80      or (
 81        all(recipients.to, .email.domain.valid == false)
 82        and all(recipients.cc, .email.domain.valid == false)
 83      )
 84    )
 85    or (
 86      length(recipients.to) == 1
 87      and any(recipients.to, .email.email == sender.email.email)
 88    )
 89  )
 90  // negate highly trusted sender domains unless they fail DMARC authentication
 91  and not (
 92    sender.email.domain.root_domain in $high_trust_sender_root_domains
 93    and coalesce(headers.auth_summary.dmarc.pass, false)
 94  )  
 95attack_types:
 96  - "Credential Phishing"
 97tactics_and_techniques:
 98  - "Encryption"
 99  - "Evasion"
100  - "PDF"
101  - "Social engineering"
102detection_methods:
103  - "Content analysis"
104  - "Exif analysis"
105  - "File analysis"
106  - "Natural Language Understanding"
107  - "Sender analysis"
108id: "f4a5fb9e-ecda-57a8-bc3c-851d64b8d06d"
to-top