Detection rules › Sublime MQL

Sublime MQL rules: inline

Inline image as message with attachment or link

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

Using inline images in lieu of HTML or text content in the message is a known technique used to bypass content based scanning engines. We've observed this technique used to deliver malware via attachments and phish credentials.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Image as content

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.html
  • body.links
  • type

Rule body

type.inbound
and length(body.html.raw) < 200
and length(body.links) > 0
and (
  // as of 20220116 there's a link parsing bug with .png inline images, so ignore those
  any(body.links, not strings.ilike(.href_url.url, "*.png"))

  // cid images are treated as attachments, so we're looking for more than 1
  or (
    length(attachments) > 1
    and any(attachments, .file_type not in $file_types_images)
  )
)
and strings.ilike(body.html.raw, "*img*cid*")
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Using inline images in lieu of HTML or text content in the message is a known technique used to bypass content based scanning engines. We've observed this technique used to deliver malware via attachments and phish credentials.

  1. inbound message
  2. length(body.html.raw) < 200
  3. length(body.links) > 0
  4. any of:
    • any of body.links where:
      • not:
        • .href_url.url matches '*.png'
    • all of:
      • length(attachments) > 1
      • any of attachments where:
        • .file_type not in $file_types_images
  5. body.html.raw matches '*img*cid*'
  6. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.html.raw, body.links, body.links[].href_url.url, type.inbound. Sensors: profile.by_sender, strings.ilike. Reference lists: $file_types_images.

Indicators matched (1)

FieldMatchValue
strings.ilikesubstring*img*cid*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      not
        body.links.href_url.url ends_with ".png"
    and
      any(attachments)
         macro "attachments[].file_type not in file_types_images"
      attachments length_compare "1"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  body.html.raw length_compare "200"
  body.html.raw wildcard "*img*cid*"
  body.links length_compare "0"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.