Detection rules › Sublime MQL
Sublime MQL rules: comp
| Rule | Severity |
|---|---|
| Compensation review with QR code in attached EML | high |
Compensation review with QR code in attached EML
#Detects inbound messages containing compensation-related terms (salary, bonus, merit, etc.) combined with review/change language that include EML attachments containing QR codes or barcodes in scanned documents.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | QR code, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// the subject contains pay related items
and (
strings.icontains(subject.subject, 'salary')
or regex.icontains(subject.subject, 'comp(?:liance|ensation|\b)')
or strings.icontains(subject.subject, 'remuneration')
or regex.icontains(subject.subject, '\bpay(?:roll|\b)')
or strings.icontains(subject.subject, 'bonus')
or strings.icontains(subject.subject, 'incentive')
or strings.icontains(subject.subject, 'merit')
or strings.icontains(subject.subject, 'handbook')
or strings.icontains(subject.subject, 'benefits')
)
// subjects include review/updates/changes
and (
strings.icontains(subject.subject, 'review')
or strings.icontains(subject.subject, 'Summary')
or strings.icontains(subject.subject, 'evaluation')
or regex.icontains(subject.subject, 'eval\b')
or strings.icontains(subject.subject, 'assessment')
or strings.icontains(subject.subject, 'appraisal')
or strings.icontains(subject.subject, 'feedback')
or strings.icontains(subject.subject, 'performance')
or strings.icontains(subject.subject, 'adjustment')
or strings.icontains(subject.subject, 'statement')
or strings.icontains(subject.subject, 'increase')
or strings.icontains(subject.subject, 'raise')
or strings.icontains(subject.subject, 'change')
or strings.icontains(subject.subject, 'modification')
or strings.icontains(subject.subject, 'distribution')
or strings.icontains(subject.subject, 'Disbursement')
or regex.icontains(subject.subject, 'revis(?:ed|ion)')
or regex.icontains(subject.subject, 'amend(?:ed|ment)')
or strings.icontains(subject.subject, 'update')
)
and any(filter(attachments,
.content_type == "message/rfc822" or .file_extension in ('eml')
),
// inspect attachments in nested EML
any(file.parse_eml(.).attachments,
any(file.explode(.),
(
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
or .scan.qr.type == "url" and .scan.qr.url.domain.valid
)
)
// inspect nested EML in body.current_thread
or (
regex.icontains(file.parse_eml(.).body.current_thread.text,
'scan|camera'
)
and regex.icontains(file.parse_eml(.).body.current_thread.text,
'\bQR\b|Q\.R\.|barcode'
)
)
// or there is a QR code found within the body of the nested body
or (
beta.scan_qr(file.html_screenshot(file.parse_eml(.).body.html)).found
and any(beta.scan_qr(file.html_screenshot(file.parse_eml(.).body.html)
).items,
.type == "url" and .url.domain.valid
)
)
)
// negate instances where proofpoint sends a review of a reported message via analyzer
and not (
sender.email.email == "analyzer@analyzer.securityeducation.com"
and any(headers.domains, .root_domain == "pphosted.com")
and headers.auth_summary.spf.pass
and headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Detects inbound messages containing compensation-related terms (salary, bonus, merit, etc.) combined with review/change language that include EML attachments containing QR codes or barcodes in scanned documents.
- inbound message
any of:
- subject.subject contains 'salary'
- subject.subject matches 'comp(?:liance|ensation|\\b)'
- subject.subject contains 'remuneration'
- subject.subject matches '\\bpay(?:roll|\\b)'
- subject.subject contains 'bonus'
- subject.subject contains 'incentive'
- subject.subject contains 'merit'
- subject.subject contains 'handbook'
- subject.subject contains 'benefits'
any of:
- subject.subject contains 'review'
- subject.subject contains 'Summary'
- subject.subject contains 'evaluation'
- subject.subject matches 'eval\\b'
- subject.subject contains 'assessment'
- subject.subject contains 'appraisal'
- subject.subject contains 'feedback'
- subject.subject contains 'performance'
- subject.subject contains 'adjustment'
- subject.subject contains 'statement'
- subject.subject contains 'increase'
- subject.subject contains 'raise'
- subject.subject contains 'change'
- subject.subject contains 'modification'
- subject.subject contains 'distribution'
- subject.subject contains 'Disbursement'
- subject.subject matches 'revis(?:ed|ion)'
- subject.subject matches 'amend(?:ed|ment)'
- subject.subject contains 'update'
any of
filter(attachments)where any holds:any of
file.parse_eml(.).attachmentswhere:any of
file.explode(.)where any holds:all of:
- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
all of:
- .scan.qr.type is 'url'
- .scan.qr.url.domain.valid
all of:
- file.parse_eml(.).body.current_thread.text matches 'scan|camera'
- file.parse_eml(.).body.current_thread.text matches '\\bQR\\b|Q\\.R\\.|barcode'
all of:
- beta.scan_qr(file.html_screenshot(file.parse_eml(.).body.html)).found
any of
beta.scan_qr(file.html_screenshot(file.parse_eml(.).body.html)).itemswhere all hold:- .type is 'url'
- .url.domain.valid
not:
all of:
- sender.email.email is 'analyzer@analyzer.securityeducation.com'
any of
headers.domainswhere:- .root_domain is 'pphosted.com'
- headers.auth_summary.spf.pass
- headers.auth_summary.dmarc.pass
Inspects: attachments[].content_type, attachments[].file_extension, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, sender.email.email, subject.subject, type.inbound. Sensors: beta.scan_qr, file.explode, file.html_screenshot, file.parse_eml, regex.icontains, strings.icontains.
Indicators matched (34)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | salary |
regex.icontains | regex | comp(?:liance|ensation|\b) |
strings.icontains | substring | remuneration |
regex.icontains | regex | \bpay(?:roll|\b) |
strings.icontains | substring | bonus |
strings.icontains | substring | incentive |
strings.icontains | substring | merit |
strings.icontains | substring | handbook |
strings.icontains | substring | benefits |
strings.icontains | substring | review |
strings.icontains | substring | Summary |
strings.icontains | substring | evaluation |
22 more
regex.icontains | regex | eval\b |
strings.icontains | substring | assessment |
strings.icontains | substring | appraisal |
strings.icontains | substring | feedback |
strings.icontains | substring | performance |
strings.icontains | substring | adjustment |
strings.icontains | substring | statement |
strings.icontains | substring | increase |
strings.icontains | substring | raise |
strings.icontains | substring | change |
strings.icontains | substring | modification |
strings.icontains | substring | distribution |
strings.icontains | substring | Disbursement |
regex.icontains | regex | revis(?:ed|ion) |
regex.icontains | regex | amend(?:ed|ment) |
strings.icontains | substring | update |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
file.explode(file.parse_eml(filter(attachments)[]).attachments[])[].scan.qr.type | equals | url |
beta.scan_qr(file.html_screenshot(file.parse_eml(filter(attachments)[]).body.html)).items[].type | equals | url |
Stages and Predicates
Stage 1: mql_rule
and
any(filter(attachments))
or
any(file.parse_eml(filter(attachments)).attachments)
any(file.explode(file.parse_eml(filter(attachments)).attachments))
or
and
file.explode(file.parse_eml(filter(attachments)[]).attachments[])[].scan.ocr.raw regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.explode(file.parse_eml(filter(attachments)[]).attachments[])[].scan.ocr.raw regex_match "scan|camera"
and
file.explode(file.parse_eml(filter(attachments)[]).attachments[])[].scan.qr.type eq "url"
file.explode(file.parse_eml(filter(attachments)[]).attachments[])[].scan.qr.url.domain.valid eq "true"
and
any(beta.scan_qr(file.html_screenshot(file.parse_eml(filter(attachments)).body.html)).items)
and
beta.scan_qr(file.html_screenshot(file.parse_eml(filter(attachments)[]).body.html)).items[].type eq "url"
beta.scan_qr(file.html_screenshot(file.parse_eml(filter(attachments)[]).body.html)).items[].url.domain.valid eq "true"
beta.scan_qr func_call "beta.scan_qr(file.html_screenshot(file.parse_eml(filter(attachments)[]).body.html)).found"
and
file.parse_eml(filter(attachments)[]).body.current_thread.text regex_match "\\bQR\\b|Q\\.R\\.|barcode"
file.parse_eml(filter(attachments)[]).body.current_thread.text regex_match "scan|camera"
not
and
any(headers.domains)
headers.domains.root_domain eq "pphosted.com"
headers.auth_summary.dmarc.pass eq "true"
headers.auth_summary.spf.pass eq "true"
sender.email.email eq "analyzer@analyzer.securityeducation.com"
or
subject.subject contains "Disbursement"
subject.subject contains "Summary"
subject.subject contains "adjustment"
subject.subject contains "appraisal"
subject.subject contains "assessment"
subject.subject contains "change"
subject.subject contains "distribution"
subject.subject contains "evaluation"
subject.subject contains "feedback"
subject.subject contains "increase"
subject.subject contains "modification"
subject.subject contains "performance"
subject.subject contains "raise"
subject.subject contains "review"
subject.subject contains "statement"
subject.subject contains "update"
subject.subject regex_match "amend(?:ed|ment)"
subject.subject regex_match "eval\\b"
subject.subject regex_match "revis(?:ed|ion)"
or
subject.subject contains "benefits"
subject.subject contains "bonus"
subject.subject contains "handbook"
subject.subject contains "incentive"
subject.subject contains "merit"
subject.subject contains "remuneration"
subject.subject contains "salary"
subject.subject regex_match "\\bpay(?:roll|\\b)"
subject.subject regex_match "comp(?:liance|ensation|\\b)"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.domains | array_any | excludes:headers.domains | |
headers.auth_summary.dmarc.pass | eq | true | excludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true" |
headers.auth_summary.spf.pass | eq | true | excludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true" |
sender.email.email | eq | analyzer@analyzer.securityeducation.com | excludes:sender.email.email field:"sender.email.email" value:"analyzer@analyzer.securityeducation.com" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
subject.subject | contains |
| field:"subject.subject" kind:contains |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |