Detection rules › Sublime MQL

Attachment: Compensation-themed DOCX with QR code credential theft

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

Detects inbound messages containing DOCX attachments with compensation or benefit-related themes that include QR codes and suspicious indicators. The rule identifies files with reward/benefit language in filenames, compensation-related content in document metadata, and QR codes that may redirect to credential theft pages. It uses natural language processing to detect credential theft intent and suspicious topics like benefit enrollment or financial communications.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesQR code, Social engineering, Impersonation: Brand

Event coverage

Rule body MQL

type.inbound
and (
  length(filter(attachments, .file_type == "docx")) >= 1
  and (
    // short or null message body
    (
      length(body.current_thread.text) < 500 or body.current_thread.text is null
    )
    // ignore disclaimers in body length calculation
    or (
      any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
                     .name == "disclaimer"
              ),
              .text
          ),
          (length(body.current_thread.text) - length(.)) < 500
      )
    )
  )
)
and (
  // attached DOCX contains a compensation review themed lure with a QR code and suspicious indicators
  any(filter(attachments, .file_type == "docx"),
      // add conditions for DOCX attachment
      (
        regex.icontains(.file_name,
                        '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
        )
        // recipient email SLD in filename
        or any(recipients.to,
               strings.icontains(..file_name, .email.domain.sld)
               and .email.domain.valid
        )
        or regex.icontains(beta.parse_exif(.).title,
                           '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
        )
      )
      // add conditions for text and any QR code within the DOCX attachment
      and (
        // conditions for QR code via text
        any(file.explode(.),
            any([.scan.strings.raw, .scan.ocr.raw],
                regex.icontains(., 'scan|camera|review and sign')
                and regex.icontains(., '\bQR\b|Q\.R\.|barcode')
            )
            or (
              .scan.qr.type == "url"
              and .scan.qr.url.url is not null
              and any(recipients.to,
                      .email.domain.valid
                      and (
                        strings.icontains(..scan.qr.url.url, .email.email)
                        or any(strings.scan_base64(..scan.qr.url.url,
                                                   format="url"
                               ),
                               strings.icontains(., ..email.email)
                        )
                      )
              )
            )
        )
        or any(file.explode(.),
               .scan.qr.type == "url" and .scan.qr.url.domain.valid
        )
      )
      // conditions for text
      and any(file.explode(.),
              // review/change terms in file content
              any([.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title],
                  (
                    regex.icontains(.,
                                    '\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b'
                    )
                  )
              )
              or (
                // recipient local_part in attachment body
                any(recipients.to,
                    strings.contains(..scan.ocr.raw, .email.local_part)
                )
                and (
                  // NLU cred_theft disposition
                  any(ml.nlu_classifier(.scan.ocr.raw).intents,
                      .name == "cred_theft" and .confidence != "low"
                  )
                  // suspicious topics
                  and any(ml.nlu_classifier(.scan.ocr.raw).topics,
                          .name in (
                            "Benefit Enrollment",
                            "Financial Communications"
                          )
                          and .confidence != "low"
                  )
                )
              )
      )
  )
)

// negate highly trusted sender domains unless they fail DMARC authentication
and not (
  sender.email.domain.root_domain in $high_trust_sender_root_domains
  and coalesce(headers.auth_summary.dmarc.pass, false)
) 

Detection logic

Scope: inbound message.

Detects inbound messages containing DOCX attachments with compensation or benefit-related themes that include QR codes and suspicious indicators. The rule identifies files with reward/benefit language in filenames, compensation-related content in document metadata, and QR codes that may redirect to credential theft pages. It uses natural language processing to detect credential theft intent and suspicious topics like benefit enrollment or financial communications.

  1. inbound message
  2. all of:
    • length(filter(attachments, .file_type == 'docx')) ≥ 1
    • any of:
      • any of:
        • length(body.current_thread.text) < 500
        • body.current_thread.text is missing
      • any of map(...) where:
        • length(body.current_thread.text) - length(.) < 500
  3. any of filter(attachments) where all hold:
    • any of:
      • .file_name matches '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
      • any of recipients.to where all hold:
        • strings.icontains(.file_name)
        • .email.domain.valid
      • beta.parse_exif(.).title matches '(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)'
    • any of:
      • any of file.explode(.) where any holds:
        • any of [.scan.strings.raw, .scan.ocr.raw] where all hold:
          • . matches 'scan|camera|review and sign'
          • . matches '\\bQR\\b|Q\\.R\\.|barcode'
        • all of:
          • .scan.qr.type is 'url'
          • .scan.qr.url.url is set
          • any of recipients.to where all hold:
            • .email.domain.valid
            • any of:
              • strings.icontains(.scan.qr.url.url)
              • any of strings.scan_base64(.scan.qr.url.url) where:
                • strings.icontains(.)
      • any of file.explode(.) where all hold:
        • .scan.qr.type is 'url'
        • .scan.qr.url.domain.valid
    • any of file.explode(.) where any holds:
      • any of [.scan.strings.raw, .scan.ocr.raw, .scan.exiftool.title] where:
        • . matches '\\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\\b'
      • all of:
        • any of recipients.to where:
          • strings.contains(.scan.ocr.raw)
        • all of:
          • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
            • .name is 'cred_theft'
            • .confidence is not 'low'
          • any of ml.nlu_classifier(.scan.ocr.raw).topics where all hold:
            • .name in ('Benefit Enrollment', 'Financial Communications')
            • .confidence is not 'low'
  4. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.email.domain.root_domain, type.inbound. Sensors: beta.parse_exif, file.explode, ml.nlu_classifier, regex.icontains, strings.contains, strings.icontains, strings.scan_base64. Reference lists: $high_trust_sender_root_domains.

Indicators matched (10)

FieldMatchValue
attachments[].file_typeequalsdocx
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsdisclaimer
regex.icontainsregex(?:salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting|employee.*(?:reward|benefit)s?)
regex.icontainsregexscan|camera|review and sign
regex.icontainsregex\bQR\b|Q\.R\.|barcode
file.explode(filter(attachments)[])[].scan.qr.typeequalsurl
regex.icontainsregex\b(?:Remuneration Overview|Updated Compensation (?:Summary|Schedule|Details)|Access Your Statements?|Staff Performance Appraisal|Compensation Adjustment|performance appraisal|Appraisal Overview|appraisal and compensation|salary (?:increment|deduction))\b
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].namememberBenefit Enrollment
ml.nlu_classifier(file.explode(filter(attachments)[])[].scan.ocr.raw).topics[].namememberFinancial Communications