EXPLORE
← Back to Explore
sublimelowRule

Link: Credential harvesting with excess padding evasion

Detects inbound messages containing credential-related action links with tall screenshot images and HTML padding techniques used to evade detection. The rule identifies messages with excessive empty div tags, non-breaking spaces, or large margin-top values that artificially increase content height while hiding malicious intent.

MITRE ATT&CK

defense-evasioninitial-access

Detection Query

type.inbound
// CTA link with action-oriented display text pointing to a different domain than the sender
and any(body.current_thread.links,
        regex.icontains(.display_text,
                        '(?:open|sign.?in|log.?in|retain|credential|secure|confirm|accept|release|review|document|deliver|go to|show|access|download|login|account)'
        )
        and .href_url.domain.root_domain != sender.email.domain.root_domain
        and not strings.icontains(.display_text, 'open source')
)
// tall rendered email with low word density
and beta.parse_exif(file.message_screenshot()).image_height > 1500
and beta.parse_exif(file.message_screenshot()).image_height * 100 / regex.count(body.html.display_text,
                                                                                '\S+'
) > 500
// html whitespace stuffing patterns
and (
  // bare div-br blocks repeated 30+ times
  regex.icontains(body.html.raw, '(?:<div>\s*<br\s*/?\s*>\s*</div>\s*){30,}')
  // style div-br blocks repeated 20+ times
  or regex.icontains(body.html.raw,
                     '(?:<div\s+style="[^"]+"\s*[^>]*>\s*<br\s*/?\s*>\s*</div>\s*){20,}'
  )
  // attributed empty div-nbsp blocks repeated 20+ times (styled/classed empty divs, e.g. Outlook Aptos)
  // requires an attribute to avoid bare <div>&nbsp;</div> newsletter spacers
  or (
    regex.icontains(body.html.raw,
                    '(?:<div\s+[^>]+>\s*(?:&nbsp;|&#160;)\s*</div>\s*){20,}'
    )
    // exclude collapsed/hidden empty divs (display:none, font-size:0, line-height:0)
    // these render to zero height and are ESP preheader artifacts, not visible stuffing
    and not regex.icontains(body.html.raw,
                            '(?:<div\s+[^>]*(?:display\s*:\s*none|font-size\s*:\s*0|line-height\s*:\s*0)[^>]*>\s*(?:&nbsp;|&#160;)\s*</div>\s*){20,}'
    )
  )
  // p-nbsp blocks repeated 25+ times
  or regex.icontains(body.html.raw,
                     '(?:<p>\s*(?:&nbsp;|&#160;)\s*</p>\s*){25,}',
                     '(<p[^\>]*><o:p>\s*(?:&nbsp;|&#160;)\s*</o:p>\s*</p>\s*){25,}'
  )
  // css margin-top or padding-top pushdown >= 1500px
  or (
    regex.icontains(body.html.raw,
                    '(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
    )
    and not regex.icontains(body.html.raw,
                            'position\s*:\s*absolute[^"]*(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
    )
    and not regex.icontains(body.html.raw,
                            'margin-left\s*:\s*\d{3,}px[^"]*(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
    )
  )
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Link: Credential harvesting with excess padding evasion"
description: "Detects inbound messages containing credential-related action links with tall screenshot images and HTML padding techniques used to evade detection. The rule identifies messages with excessive empty div tags, non-breaking spaces, or large margin-top values that artificially increase content height while hiding malicious intent."
type: "rule"
severity: "low"
source: |
  type.inbound
  // CTA link with action-oriented display text pointing to a different domain than the sender
  and any(body.current_thread.links,
          regex.icontains(.display_text,
                          '(?:open|sign.?in|log.?in|retain|credential|secure|confirm|accept|release|review|document|deliver|go to|show|access|download|login|account)'
          )
          and .href_url.domain.root_domain != sender.email.domain.root_domain
          and not strings.icontains(.display_text, 'open source')
  )
  // tall rendered email with low word density
  and beta.parse_exif(file.message_screenshot()).image_height > 1500
  and beta.parse_exif(file.message_screenshot()).image_height * 100 / regex.count(body.html.display_text,
                                                                                  '\S+'
  ) > 500
  // html whitespace stuffing patterns
  and (
    // bare div-br blocks repeated 30+ times
    regex.icontains(body.html.raw, '(?:<div>\s*<br\s*/?\s*>\s*</div>\s*){30,}')
    // style div-br blocks repeated 20+ times
    or regex.icontains(body.html.raw,
                       '(?:<div\s+style="[^"]+"\s*[^>]*>\s*<br\s*/?\s*>\s*</div>\s*){20,}'
    )
    // attributed empty div-nbsp blocks repeated 20+ times (styled/classed empty divs, e.g. Outlook Aptos)
    // requires an attribute to avoid bare <div>&nbsp;</div> newsletter spacers
    or (
      regex.icontains(body.html.raw,
                      '(?:<div\s+[^>]+>\s*(?:&nbsp;|&#160;)\s*</div>\s*){20,}'
      )
      // exclude collapsed/hidden empty divs (display:none, font-size:0, line-height:0)
      // these render to zero height and are ESP preheader artifacts, not visible stuffing
      and not regex.icontains(body.html.raw,
                              '(?:<div\s+[^>]*(?:display\s*:\s*none|font-size\s*:\s*0|line-height\s*:\s*0)[^>]*>\s*(?:&nbsp;|&#160;)\s*</div>\s*){20,}'
      )
    )
    // p-nbsp blocks repeated 25+ times
    or regex.icontains(body.html.raw,
                       '(?:<p>\s*(?:&nbsp;|&#160;)\s*</p>\s*){25,}',
                       '(<p[^\>]*><o:p>\s*(?:&nbsp;|&#160;)\s*</o:p>\s*</p>\s*){25,}'
    )
    // css margin-top or padding-top pushdown >= 1500px
    or (
      regex.icontains(body.html.raw,
                      '(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
      )
      and not regex.icontains(body.html.raw,
                              'position\s*:\s*absolute[^"]*(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
      )
      and not regex.icontains(body.html.raw,
                              'margin-left\s*:\s*\d{3,}px[^"]*(?:margin|padding)-top\s*:\s*(?:1[5-9]\d{2}|[2-9]\d{3}|\d{5,})px'
      )
    )
  )
attack_types:
  - "Credential Phishing"
tactics_and_techniques:
  - "Evasion"
  - "Social engineering"
detection_methods:
  - "Content analysis"
  - "HTML analysis"
  - "Exif analysis"
  - "URL screenshot"
id: "5591f618-aed0-579d-9875-cdebdd72c6d2"