EXPLORE
← Back to Explore
sublimelowRule

Spam: Commonly observed formatting of unauthorized free giveaways

Detects commonly observed formatting of unauthorized giveaways, free tools, and products by multiple different brands.

MITRE ATT&CK

initial-access

Detection Query

type.inbound
and (
  (
    any(html.xpath(body.html, "//div[contains(@style, 'BACKGROUND: URL')]").nodes,
        .raw is not null
    )
  )
  or (
    any(body.links,
        any([
              "blob.core.windows.net",
              "click.email.formula1.com",
              "firmy-praha.eu"
            ],
            ..href_url.domain.domain == .
            or strings.ends_with(..href_url.domain.domain, .)
        )
    )
  )
)
and (
  (
    // subject has # plus random characters only
    regex.icontains(subject.base, "#[a-z0-9]{5,}?")
    // plus one of these
    and (
      // display name has a # + random characters only
      regex.icontains(sender.display_name, "#[a-z0-9]{5,}?")
      // subject starts with a period (yes, both subject cases should be true)
      or strings.starts_with(subject.base, ".")
      // Display name contains at least 2 emojis
      or length(distinct(map(regex.extract(sender.display_name,
                                           '(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
                             ),
                             .full_match
                         )
                )
      ) >= 2
    )
  )
  or (
    // Subject contains at least 2 emojias
    length(distinct(map(regex.extract(subject.base,
                                      '(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
                        ),
                        .full_match
                    )
           )
    ) >= 2
  )
  or 
  // another variant with different strings that have numbers but the same pattern is in both subject and displayname
  (
    // subject has # plus random characters & numbers
    regex.icontains(subject.base, "#[1-9a-z]+")
    // plus one of these
    and (
      regex.icontains(sender.display_name, "#[1-9a-z]+")
      or strings.icontains(sender.display_name, "rewards")
    )
  )
  or (
    // or prornotions (promotions) once confusables are stripped in subject
    strings.icontains(strings.replace_confusables(subject.base), "prornotions")
    // and rewards in display name
    and strings.icontains(sender.display_name, "rewards")
  )
  or (
    // subject has * plus 4 random characters and numbers *
    regex.icontains(subject.base, '\*[1-9a-z]{4,}\*')
    // same with the display name
    and regex.icontains(sender.display_name, '\*[1-9a-z]{4,}\*')
  )
  or (
    // subject and display name has two *
    strings.count(subject.base, "*") == 2
    and strings.count(sender.display_name, "*") == 2
  )
  or (
    // subject has string of random characters and numbers
    // checking if string has 1 uppercase, 1 lowercase and 1 number
    any(regex.extract(subject.base, '(?:-{1,2}|\s)([a-zA-Z0-9]{11,})'),
        regex.contains(.full_match, '[A-Z]')
        and regex.contains(.full_match, '[a-z]')
        and regex.contains(.full_match, '[0-9]')
        // some matches are legit but they are 35+ characters
        and length(.full_match) <= 30
    )
    // negating support thread email subjects containg multiple : in their IDs
    and not regex.count(subject.base, ':') > 5
  )
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Spam: Commonly observed formatting of unauthorized free giveaways"
description: "Detects commonly observed formatting of unauthorized giveaways, free tools, and products by multiple different brands."
type: "rule"
severity: "low"
source: |
  type.inbound
  and (
    (
      any(html.xpath(body.html, "//div[contains(@style, 'BACKGROUND: URL')]").nodes,
          .raw is not null
      )
    )
    or (
      any(body.links,
          any([
                "blob.core.windows.net",
                "click.email.formula1.com",
                "firmy-praha.eu"
              ],
              ..href_url.domain.domain == .
              or strings.ends_with(..href_url.domain.domain, .)
          )
      )
    )
  )
  and (
    (
      // subject has # plus random characters only
      regex.icontains(subject.base, "#[a-z0-9]{5,}?")
      // plus one of these
      and (
        // display name has a # + random characters only
        regex.icontains(sender.display_name, "#[a-z0-9]{5,}?")
        // subject starts with a period (yes, both subject cases should be true)
        or strings.starts_with(subject.base, ".")
        // Display name contains at least 2 emojis
        or length(distinct(map(regex.extract(sender.display_name,
                                             '(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
                               ),
                               .full_match
                           )
                  )
        ) >= 2
      )
    )
    or (
      // Subject contains at least 2 emojias
      length(distinct(map(regex.extract(subject.base,
                                        '(?P<emoji>[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}])'
                          ),
                          .full_match
                      )
             )
      ) >= 2
    )
    or 
    // another variant with different strings that have numbers but the same pattern is in both subject and displayname
    (
      // subject has # plus random characters & numbers
      regex.icontains(subject.base, "#[1-9a-z]+")
      // plus one of these
      and (
        regex.icontains(sender.display_name, "#[1-9a-z]+")
        or strings.icontains(sender.display_name, "rewards")
      )
    )
    or (
      // or prornotions (promotions) once confusables are stripped in subject
      strings.icontains(strings.replace_confusables(subject.base), "prornotions")
      // and rewards in display name
      and strings.icontains(sender.display_name, "rewards")
    )
    or (
      // subject has * plus 4 random characters and numbers *
      regex.icontains(subject.base, '\*[1-9a-z]{4,}\*')
      // same with the display name
      and regex.icontains(sender.display_name, '\*[1-9a-z]{4,}\*')
    )
    or (
      // subject and display name has two *
      strings.count(subject.base, "*") == 2
      and strings.count(sender.display_name, "*") == 2
    )
    or (
      // subject has string of random characters and numbers
      // checking if string has 1 uppercase, 1 lowercase and 1 number
      any(regex.extract(subject.base, '(?:-{1,2}|\s)([a-zA-Z0-9]{11,})'),
          regex.contains(.full_match, '[A-Z]')
          and regex.contains(.full_match, '[a-z]')
          and regex.contains(.full_match, '[0-9]')
          // some matches are legit but they are 35+ characters
          and length(.full_match) <= 30
      )
      // negating support thread email subjects containg multiple : in their IDs
      and not regex.count(subject.base, ':') > 5
    )
  )

attack_types:
  - "Spam"
tactics_and_techniques:
  - "Impersonation: Brand"
  - "Social engineering"
detection_methods:
  - "Content analysis"
  - "HTML analysis"
  - "Sender analysis"
  - "URL analysis"
id: "8bc49fa3-5fdc-5eca-a9cd-f9f5ecf04a7c"