Detection rules › Sublime MQL

Attachment: Encrypted PDF with credential theft body

Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

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

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEncryption, Evasion, PDF, Social engineering

Event coverage

Rule body MQL

type.inbound
and any(filter(attachments, .file_type == "pdf"),
        any(file.explode(.),
            any(.scan.exiftool.fields, .key == "Encryption")
            or (
              .scan.entropy.entropy > 7
              and any(.scan.strings.strings, strings.icontains(., "/Encrypt"))
            )
        )
        // Encrypted PDFs do not have child nodes with any data
        and all(filter(file.explode(.), .depth > 0), .size == 0)
)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in ("medium", "high")
  )
  or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
         .name == "cred_theft" and .confidence in ("medium", "high")
  )
  or regex.icontains(body.current_thread.text,
                     'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
                     '(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
                     'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
                     '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}PDF(?:\S+\s+){0,3}pass(?:word|code)'
  )
  or (
    (
      length(body.current_thread.text) <= 10
      or (body.current_thread.text is null)
    )
    and any(body.previous_threads,
            regex.icontains(.text,
                            'PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)',
                            '(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:',
                            'This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?',
                            '(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}PDF(?:\S+\s+){0,3}pass(?:word|code)'
            )
    )
  )
)
// not forwards/replies
and not (
  (length(headers.references) > 0 or headers.in_reply_to is not null)
  and (subject.is_forward or subject.is_reply)
  and length(body.previous_threads) >= 1
)
and (
  (
    profile.by_sender_email().prevalence in ("new", "outlier")
    and not profile.by_sender_email().solicited
  )
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  or (
    length(recipients.to) == 0
    or all(recipients.to,
           strings.ilike(.display_name, "undisclosed?recipients")
    )
  )
  or (
    length(recipients.to) == 1
    and any(recipients.to, .email.email == sender.email.email)
  )
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

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

  1. inbound message
  2. any of filter(attachments) where all hold:
    • any of file.explode(.) where any holds:
      • any of .scan.exiftool.fields where:
        • .key is 'Encryption'
      • all of:
        • .scan.entropy.entropy > 7
        • any of .scan.strings.strings where:
          • . contains '/Encrypt'
    • all of filter(...) where:
      • .size is 0
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • body.current_thread.text matches any of 4 patterns
      • PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)
      • (Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:
      • This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?
      • (?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}PDF(?:\S+\s+){0,3}pass(?:word|code)
    • all of:
      • any of:
        • length(body.current_thread.text) ≤ 10
        • body.current_thread.text is missing
      • any of body.previous_threads where:
        • .text matches any of 4 patterns
          • PDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)
          • (Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:
          • This\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?
          • (?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}PDF(?:\S+\s+){0,3}pass(?:word|code)
  4. not:
    • all of:
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
      • any of:
        • subject.is_forward
        • subject.is_reply
      • length(body.previous_threads) ≥ 1
  5. any of:
    • all of:
      • profile.by_sender_email().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • any of:
      • length(recipients.to) is 0
      • all of recipients.to where:
        • .display_name matches 'undisclosed?recipients'
    • all of:
      • length(recipients.to) is 1
      • any of recipients.to where:
        • .email.email is sender.email.email
  6. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: attachments[].file_type, body.current_thread.text, body.previous_threads, body.previous_threads[].text, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, recipients.to, recipients.to[].display_name, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, subject.is_forward, subject.is_reply, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (14)

FieldMatchValue
attachments[].file_typeequalspdf
file.explode(filter(attachments)[])[].scan.exiftool.fields[].keyequalsEncryption
strings.icontainssubstring/Encrypt
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidencemembermedium
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidencememberhigh
regex.icontainsregexPDF\s*(?:Access|Preview|Unlock|Decrypt|passcode)
regex.icontainsregex(Access|Preview|Unlock|Decrypt|Pass)\s*(?:word|code)\s*(?:\S+\s+){0,3}PDF\s*is?\s*:
regex.icontainsregexThis\s+(?:file|document|pdf)\s+is\s+(?:password[-\s]?)\s+protected\.\s*The\s+password\s+is\s*:?
2 more
regex.icontainsregex(?:Access|Preview|Unlock|Decrypt)\s+(?:\S+\s+){0,3}PDF(?:\S+\s+){0,3}pass(?:word|code)
strings.ilikesubstringundisclosed?recipients