Detection rules › Sublime MQL

Attachment: Legal themed message or PDF with suspicious indicators

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

Detects messages with short body content or emoji containing PDF attachments from suspicious creators that include legal and compliance language with embedded malicious links, URL shorteners, or newly registered domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Extortion, BEC/Fraud
Tactics and techniquesEvasion, PDF, Social engineering

Event coverage

Rule body MQL

type.inbound
// short body or contains emoji
and (
  length(body.current_thread.text) < 1500
  or regex.contains(body.plain.raw,
                    '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
  )
  or regex.contains(subject.base,
                    '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
  )
)

// is not a reply
and length(headers.references) == 0
and headers.in_reply_to is null
and (
  ( // only one attachment
    length(attachments) == 1
    // or, any 2 attachments share the ~same file name
    or any(attachments,
           any(regex.extract(.file_name,
                             // the regex extracts the file name, discarding the file extention and any numbers in parens
                             // "test.txt" and "test (1).pdf" become "test"
                             '(?P<file_name>.*?)(?:\s*\([^)]+\))*\.[^.]+$'
               ),
               length(filter(attachments,
                             strings.istarts_with(.file_name,
                                                  ..named_groups["file_name"]
                             )
                      )
               ) > 1
           )
    )
  )
  // suspicious creator
  and any(attachments,
          (.file_extension == "pdf" or .file_type == "pdf")
          and any(file.explode(.),
                  strings.ilike(.scan.exiftool.producer,
                                "*Google Docs Renderer*",
                                "*Skia/PDF*",
                                "*Neevia Document Converter*"
                  )
                  or strings.istarts_with(.scan.exiftool.creator, "wkhtmltopdf")
          )
  )
)
and (
  // legal language in body with suspicious link in attachment
  (
    any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == "Legal and Compliance" and .confidence in ("medium", "high")
    )
    and any(attachments,
            (.file_extension == "pdf" or .file_type == "pdf")
            and any(file.explode(.),
                    0 < length(.scan.pdf.urls) < 5
                    and (
                      any(.scan.pdf.urls,
                          // with links that are URL shortners
                          .domain.root_domain in $url_shorteners
                          or .domain.domain in $url_shorteners
                          or network.whois(.domain).days_old < 14
                          // when visiting those links, the link it is sus
                          or ml.link_analysis(.).effective_url.domain.tld in $suspicious_tlds
                          or ml.link_analysis(.).credphish.contains_captcha
                          or ml.link_analysis(.).credphish.disposition == "phishing"
                          or strings.icontains(ml.link_analysis(.).final_dom.display_text,
                                               "I'm Human"
                          )
                      )
                    )
            )
    )
  )
  // no body text, legal language in attachment
  or (
    length(body.current_thread.text) < 50
    and any(attachments,
            (.file_extension == "pdf" or .file_type == "pdf")
            and any(file.explode(.),
                    (
                      length(ml.nlu_classifier(.scan.ocr.raw).topics) == 1
                      and any(ml.nlu_classifier(.scan.ocr.raw).topics,
                              .name == "Legal and Compliance"
                              and .confidence in ("medium", "high")
                      )
                      and not any(ml.nlu_classifier(.scan.ocr.raw).entities,
                                  .name == "sender"
                                  and .text =~ sender.display_name
                      )
                    )
                    // foreign language indicators
                    or regex.icontains(.scan.ocr.raw,
                                       'pornograph(y|ie)',
                                       'interpol\b',
                                       'europol',
                                       'dissuade',
                                       // French indicators, seen in threatening language
                                       'ce jeu en ligne',
                                       'vraie vie'
                    )
            )
    )
  )
)

Detection logic

Scope: inbound message.

Detects messages with short body content or emoji containing PDF attachments from suspicious creators that include legal and compliance language with embedded malicious links, URL shorteners, or newly registered domains.

  1. inbound message
  2. any of:
    • length(body.current_thread.text) < 1500
    • body.plain.raw matches '[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]'
    • subject.base matches '[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]'
  3. length(headers.references) is 0
  4. headers.in_reply_to is missing
  5. all of:
    • any of:
      • length(attachments) is 1
      • any of attachments where:
        • any of regex.extract(.file_name) where:
          • length(filter(attachments, strings.istarts_with(.file_name, .named_groups['file_name']))) > 1
    • any of attachments where all hold:
      • any of:
        • .file_extension is 'pdf'
        • .file_type is 'pdf'
      • any of file.explode(.) where any holds:
        • .scan.exiftool.producer matches any of 3 patterns
          • *Google Docs Renderer*
          • *Skia/PDF*
          • *Neevia Document Converter*
        • .scan.exiftool.creator starts with 'wkhtmltopdf'
  6. any of:
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name is 'Legal and Compliance'
        • .confidence in ('medium', 'high')
      • any of attachments where all hold:
        • any of:
          • .file_extension is 'pdf'
          • .file_type is 'pdf'
        • any of file.explode(.) where all hold:
          • all of:
            • length(.scan.pdf.urls) > 0
            • length(.scan.pdf.urls) < 5
          • any of .scan.pdf.urls where any holds:
            • .domain.root_domain in $url_shorteners
            • .domain.domain in $url_shorteners
            • network.whois(.domain).days_old < 14
            • ml.link_analysis(.).effective_url.domain.tld in $suspicious_tlds
            • ml.link_analysis(.).credphish.contains_captcha
            • ml.link_analysis(.).credphish.disposition is 'phishing'
            • ml.link_analysis(.).final_dom.display_text contains "I'm Human"
    • all of:
      • length(body.current_thread.text) < 50
      • any of attachments where all hold:
        • any of:
          • .file_extension is 'pdf'
          • .file_type is 'pdf'
        • any of file.explode(.) where any holds:
          • all of:
            • length(ml.nlu_classifier(.scan.ocr.raw).topics) is 1
            • any of ml.nlu_classifier(.scan.ocr.raw).topics where all hold:
              • .name is 'Legal and Compliance'
              • .confidence in ('medium', 'high')
            • not:
              • any of ml.nlu_classifier(.scan.ocr.raw).entities where all hold:
                • .name is 'sender'
                • .text is sender.display_name
          • .scan.ocr.raw matches any of 6 patterns
            • pornograph(y|ie)
            • interpol\b
            • europol
            • dissuade
            • ce jeu en ligne
            • vraie vie

Inspects: attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.plain.raw, headers.in_reply_to, headers.references, sender.display_name, subject.base, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, network.whois, regex.contains, regex.extract, regex.icontains, strings.icontains, strings.ilike, strings.istarts_with. Reference lists: $suspicious_tlds, $url_shorteners.

Indicators matched (22)

FieldMatchValue
regex.containsregex[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]
regex.extractregex(?P<file_name>.*?)(?:\s*\([^)]+\))*\.[^.]+$
attachments[].file_extensionequalspdf
attachments[].file_typeequalspdf
strings.ilikesubstring*Google Docs Renderer*
strings.ilikesubstring*Skia/PDF*
strings.ilikesubstring*Neevia Document Converter*
strings.istarts_withprefixwkhtmltopdf
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsLegal and Compliance
ml.nlu_classifier(body.current_thread.text).topics[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).topics[].confidencememberhigh
strings.icontainssubstringI'm Human
10 more
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].nameequalsLegal and Compliance
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidencemembermedium
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].confidencememberhigh
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].nameequalssender
regex.icontainsregexpornograph(y|ie)
regex.icontainsregexinterpol\b
regex.icontainsregexeuropol
regex.icontainsregexdissuade
regex.icontainsregexce jeu en ligne
regex.icontainsregexvraie vie