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