• Sublime Core Feed
High Severity

QR Code with suspicious indicators

Labels

Credential Phishing
QR code
Social engineering
Content analysis
Header analysis
Computer Vision
Natural Language Understanding
QR code analysis
Sender analysis
URL analysis

Description

This rule flags messages with QR codes in attachments when there are three or fewer attachments. If no attachments are present, the rule captures a screenshot of the message for analysis. Additional triggers include: sender's name containing the recipient's SLD, recipient's email mentioned in the body, an empty message body, a suspicious subject, or undisclosed recipients.

References

No references.

Sublime Security
Created Oct 5th, 2023 • Last updated Apr 29th, 2024
Feed Source
Sublime Core Feed
Source
GitHub
type.inbound
and (
  (
    length(attachments) <= 3
    or (
      any(attachments, length(ml.logo_detect(.).brands) > 0)
      and length(attachments) <= 10
    )
  )
  and (
    any(attachments,
        .file_type in $file_types_images
        and any(file.explode(.),
                .scan.qr.type is not null
                and regex.contains(.scan.qr.data, '\.')
                // exclude images taken with mobile cameras and screenshots from android
                and not any(.scan.exiftool.fields,
                            .key == "Model"
                            or (
                              .key == "Software"
                              and strings.starts_with(.value, "Android")
                            )
                )
                // exclude images taken with mobile cameras and screenshots from Apple
                and not any(.scan.exiftool.fields,
                            .key == "DeviceManufacturer"
                            and .value == "Apple Computer Inc."
                )
                and not (
                  .scan.exiftool.image_height > 3000
                  or .scan.exiftool.image_width > 3000
                )
        )
    )
    or (
      length(attachments) == 0
      and any(file.explode(beta.message_screenshot()),
              .scan.exiftool.image_height < 2000
              and .scan.exiftool.image_width < 2000
              and .scan.qr.type is not null
              and regex.contains(.scan.qr.data, '\.')
      )
    )
  )
  and (
    any(recipients.to,
        strings.icontains(sender.display_name, .email.domain.sld)
    )
    or length(body.current_thread.text) is null
    or body.current_thread.text == ""
    or regex.contains(subject.subject,
                      "(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
    )
    or (any(recipients.to, strings.icontains(subject.subject, .display_name)))
    or (
      regex.icontains(subject.subject,
                      "termination.*notice",
                      "38417",
                      ":completed",
                      "[il1]{2}mit.*ma[il1]{2} ?bo?x",
                      "[il][il][il]egai[ -]",
                      "[li][li][li]ega[li] attempt",
                      "[ng]-?[io]n .*block",
                      "[ng]-?[io]n .*cancel",
                      "[ng]-?[io]n .*deactiv",
                      "[ng]-?[io]n .*disabl",
                      "action.*required",
                      "abandon.*package",
                      "about.your.account",
                      "acc(ou)?n?t (is )?on ho[li]d",
                      "acc(ou)?n?t.*terminat",
                      "acc(oun)?t.*[il1]{2}mitation",
                      "access.*limitation",
                      "account (will be )?block",
                      "account.*de-?activat",
                      "account.*locked",
                      "account.*re-verification",
                      "account.*security",
                      "account.*suspension",
                      "account.has.been",
                      "account.has.expired",
                      "account.will.be.blocked",
                      "account v[il]o[li]at",
                      "activity.*acc(oun)?t",
                      "almost.full",
                      "app[li]e.[il]d",
                      "authenticate.*account",
                      "been.*suspend",
                      "clos.*of.*account.*processed",
                      "confirm.your.account",
                      "courier.*able",
                      "deactivation.*in.*progress",
                      "delivery.*attempt.*failed",
                      "document.received",
                      "documented.*shared.*with.*you",
                      "dropbox.*document",
                      "e-?ma[il1]+ .{010}suspen",
                      "e-?ma[il1]{1} user",
                      "e-?ma[il1]{2} acc",
                      "e-?ma[il1]{2}.*up.?grade",
                      "e.?ma[il1]{2}.*server",
                      "e.?ma[il1]{2}.*suspend",
                      "email.update",
                      "faxed you",
                      "fraud(ulent)?.*charge",
                      "from.helpdesk",
                      "fu[il1]{2}.*ma[il1]+[ -]?box",
                      "has.been.*suspended",
                      "has.been.limited",
                      "have.locked",
                      "he[li]p ?desk upgrade",
                      "heipdesk",
                      "i[il]iega[il]",
                      "ii[il]ega[il]",
                      "incoming e?mail",
                      "incoming.*fax",
                      "lock.*security",
                      "ma[il1]{1}[ -]?box.*quo",
                      "ma[il1]{2}[ -]?box.*fu[il1]",
                      "ma[il1]{2}box.*[il1]{2}mit",
                      "ma[il1]{2}box stor",
                      "mail on.?hold",
                      "mail.*box.*migration",
                      "mail.*de-?activat",
                      "mail.update.required",
                      "mails.*pending",
                      "messages.*pending",
                      "missed.*shipping.*notification",
                      "missed.shipment.notification",
                      "must.update.your.account",
                      "new [sl][io]g?[nig][ -]?in from",
                      "new voice ?-?mail",
                      "notifications.*pending",
                      "office.*3.*6.*5.*suspend",
                      "office365",
                      "on google docs with you",
                      "online doc",
                      "password.*compromised",
                      "periodic maintenance",
                      "potential(ly)? unauthorized",
                      "refund not approved",
                      "report",
                      "revised.*policy",
                      "scam",
                      "scanned.?invoice",
                      "secured?.update",
                      "security breach",
                      "securlty",
                      "signed.*delivery",
                      "status of your .{314}? ?delivery",
                      "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty",
                      "suspicious.*sign.*[io]n",
                      "suspicious.activit",
                      "temporar(il)?y deactivate",
                      "temporar[il1]{2}y disab[li]ed",
                      "temporarily.*lock",
                      "un-?usua[li].activity",
                      "unable.*deliver",
                      "unauthorized.*activit",
                      "unauthorized.device",
                      "undelivered message",
                      "unread.*doc",
                      "unusual.activity",
                      "upgrade.*account",
                      "upgrade.notice",
                      "urgent message",
                      "urgent.verification",
                      "v[il1]o[li1]at[il1]on security",
                      "va[il1]{1}date.*ma[il1]{2}[ -]?box",
                      "verification ?-?require",
                      "verification( )?-?need",
                      "verify.your?.account",
                      "web ?-?ma[il1]{2}",
                      "web[ -]?ma[il1]{2}",
                      "will.be.suspended",
                      "your (customer )?account .as",
                      "your.office.365",
                      "your.online.access"
      )
      or any($suspicious_subjects, strings.icontains(subject.subject, .))
      or regex.icontains(sender.display_name,
                         "Admin",
                         "Administrator",
                         "Alert",
                         "Assistant",
                         "Billing",
                         "Benefits",
                         "Bonus",
                         "CEO",
                         "CFO",
                         "CIO",
                         "CTO",
                         "Chairman",
                         "Claim",
                         "Confirm",
                         "Critical",
                         "Customer Service",
                         "Deal",
                         "Discount",
                         "Director",
                         "Exclusive",
                         "Executive",
                         "Fax",
                         "Free",
                         "Gift",
                         "/bHR/b",
                         "Helpdesk",
                         "Human Resources",
                         "Immediate",
                         "Important",
                         "Info",
                         "Information",
                         "Invoice",
                         '\bIT\b',
                         "Legal",
                         "Lottery",
                         "Management",
                         "Manager",
                         "Member Services",
                         "Notification",
                         "Offer",
                         "Operations",
                         "Order",
                         "Partner",
                         "Payment",
                         "Payroll",
                         "President",
                         "Premium",
                         "Prize",
                         "Receipt",
                         "Refund",
                         "Registrar",
                         "Required",
                         "Reward",
                         "Sales",
                         "Secretary",
                         "Security",
                         "Service",
                         "Signature",
                         "Storage",
                         "Support",
                         "Sweepstakes",
                         "System",
                         "Tax",
                         "Tech Support",
                         "Update",
                         "Upgrade",
                         "Urgent",
                         "Validate",
                         "Verify",
                         "VIP",
                         "Webmaster",
                         "Winner",
      )
    )
    or (
      (
        length(recipients.to) == 0
        or all(recipients.to, .display_name == "Undisclosed recipients")
      )
      and length(recipients.cc) == 0
      and length(recipients.bcc) == 0
    )
    or any(file.explode(beta.message_screenshot()),
           (
             .scan.qr.url.domain.tld in $suspicious_tlds
             and .scan.qr.url.domain.root_domain != "app.link"
           )
           or 
           // linkanalysis phishing disposition
           any([ml.link_analysis(.scan.qr.url)],
               .credphish.disposition == "phishing"
           )
    )
    or any(attachments,
           .file_type in $file_types_images
           and any(file.explode(.),
                   (
                     .scan.qr.url.domain.tld in $suspicious_tlds
                     and .scan.qr.url.domain.root_domain != "app.link"
                   )
                   and .scan.qr.url.domain.root_domain not in $org_domains
           )
    )
    or sender.email.domain.tld in $suspicious_tlds
  )
)

// sender profile is new or outlier
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_false_positives
  )
)

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

Playground

Test against your own EMLs or sample data.

Share

Post about this on your socials.

Get Started. Today.

Managed or self-managed. No MX changes.

Get Started