Attachment: Compensation review lure with QR code

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

Sublime rule (View on GitHub)

  1name: "Attachment: Compensation review lure with QR code"
  2description: "Detects PDF attachments containing compensation or payroll-themed content with QR codes from unsolicited or suspicious senders."
  3type: "rule"
  4severity: "high"
  5source: |
  6  type.inbound
  7  and (
  8    (
  9      length(attachments) == 1
 10      and any(attachments,
 11              .content_type == "application/pdf" or .file_type == "pdf"
 12      )
 13    )
 14    and (
 15      // short or null message body
 16      (
 17        length(body.current_thread.text) < 500 or body.current_thread.text is null
 18      )
 19      // ignore disclaimers in body length calculation
 20      or (
 21        any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
 22                       .name == "disclaimer"
 23                ),
 24                .text
 25            ),
 26            (length(body.current_thread.text) - length(.)) < 500
 27        )
 28      )
 29    )
 30  )
 31  and (
 32    // attached PDF contains a compensation review themed lure with a QR code and suspicious indicators
 33    any(attachments,
 34        // add conditions for pdf attachment
 35        (
 36          regex.icontains(.file_name,
 37                          'salary|pay(?:roll)|bonus|comp(?:ensation|liance|\b)|remuneration|disbursement|incentive|merit|vesting'
 38          )
 39          // recipient email SLD in filename
 40          or any(recipients.to,
 41                 strings.icontains(..file_name, .email.domain.sld)
 42                 and .email.domain.valid
 43          )
 44        )
 45        // add conditions for text and any QR code within the pdf attachment
 46        and (
 47          // conditions for QR code via text
 48          any(file.explode(.),
 49              any([.scan.strings.raw, .scan.ocr.raw],
 50                  regex.icontains(., 'scan|camera')
 51                  and regex.icontains(., '\bQR\b|Q\.R\.|barcode')
 52              )
 53          )
 54          or any(file.explode(.),
 55                 .scan.qr.type == "url" and .scan.qr.url.domain.valid
 56          )
 57        )
 58        // conditions for text
 59        and any(file.explode(.),
 60                // review/change terms in file content      
 61                any([.scan.strings.raw, .scan.ocr.raw],
 62                    (
 63                      regex.icontains(.,
 64                                      '\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)\b'
 65                      )
 66                    )
 67                )
 68                or (
 69                  // recipient local_part in attachment body
 70                  any(recipients.to,
 71                      strings.contains(..scan.ocr.raw, .email.local_part)
 72                  )
 73                  and (
 74                    // NLU cred_theft disposition
 75                    any(ml.nlu_classifier(.scan.ocr.raw).intents,
 76                        .name == "cred_theft" and .confidence != "low"
 77                    )
 78                    // suspicious topics
 79                    and any(ml.nlu_classifier(.scan.ocr.raw).topics,
 80                            .name in (
 81                              "Benefit Enrollment",
 82                              "Financial Communications"
 83                            )
 84                            and .confidence != "low"
 85                    )
 86                  )
 87                )
 88        )
 89    )
 90  )
 91  and (
 92    not profile.by_sender_email().solicited
 93    or not profile.by_sender_email().any_messages_benign
 94    or (
 95      profile.by_sender_email().any_messages_malicious_or_spam
 96      and not profile.by_sender_email().any_messages_benign
 97    )
 98    // account for spoofed sender domains
 99    or (
100      sender.email.domain.domain in $org_domains
101      and not coalesce(headers.auth_summary.dmarc.pass, false)
102    )
103  )
104  
105  // negate highly trusted sender domains unless they fail DMARC authentication
106  and (
107    (
108      sender.email.domain.root_domain in $high_trust_sender_root_domains
109      and not headers.auth_summary.dmarc.pass
110    )
111    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
112  )  
113attack_types:
114  - "Credential Phishing"
115tactics_and_techniques:
116  - "PDF"
117  - "QR code"
118  - "Social engineering"
119detection_methods:
120  - "File analysis"
121  - "Optical Character Recognition"
122  - "QR code analysis"
123  - "Natural Language Understanding"
124  - "Sender analysis"
125  - "Header analysis"
126id: "9fd8185c-e2a7-50d0-895d-9f6b1a1c43ab"
to-top