Detection rules › Sublime MQL

Attachment: Compensation review lure with QR code

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

Detects PDF attachments containing compensation or payroll-themed content with QR codes from unsolicited or suspicious senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesPDF, QR code, Social engineering

Event coverage

Rule body MQL

type.inbound
and (
  any(attachments, .content_type == "application/pdf" or .file_type == "pdf")
  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 PDF contains a compensation review themed lure with a QR code and suspicious indicators
  any(attachments,
      // add conditions for pdf attachment
      (
        regex.icontains(.file_name,
                        'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting'
        )
        // 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'
        )
      )
      // add conditions for text and any QR code within the pdf 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 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"
                  )
                )
              )
      )
  )
)
and (
  not profile.by_sender_email().solicited
  or not profile.by_sender_email().any_messages_benign
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  // account for spoofed sender domains
  or (
    sender.email.domain.domain in $org_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
)

// 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.

Detects PDF attachments containing compensation or payroll-themed content with QR codes from unsolicited or suspicious senders.

  1. inbound message
  2. all of:
    • any of attachments where any holds:
      • .content_type is 'application/pdf'
      • .file_type is 'pdf'
    • 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 attachments where all hold:
    • any of:
      • .file_name matches 'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\\b)|remuneration|disbursement|incentive|merit|vesting'
      • 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'
    • any of:
      • any of file.explode(.) where:
        • any of [.scan.strings.raw, .scan.ocr.raw] where all hold:
          • . matches 'scan|camera|review and sign'
          • . matches '\\bQR\\b|Q\\.R\\.|barcode'
      • 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. any of:
    • not:
      • profile.by_sender_email().solicited
    • not:
      • profile.by_sender_email().any_messages_benign
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • all of:
      • sender.email.domain.domain in $org_domains
      • not:
        • coalesce(headers.auth_summary.dmarc.pass)
  5. 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[].content_type, attachments[].file_name, 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.local_part, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: beta.parse_exif, file.explode, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.contains, strings.icontains. Reference lists: $high_trust_sender_root_domains, $org_domains.

Indicators matched (11)

FieldMatchValue
attachments[].content_typeequalsapplication/pdf
attachments[].file_typeequalspdf
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsdisclaimer
regex.icontainsregexsalary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting
regex.icontainsregexscan|camera|review and sign
regex.icontainsregex\bQR\b|Q\.R\.|barcode
file.explode(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(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].namememberBenefit Enrollment
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).topics[].namememberFinancial Communications