import json import re from typing import Any from typing import Optional import customtkinter import dns.resolver import nmap import openai import requests from rich.progress import track customtkinter.set_appearance_mode("dark") customtkinter.set_default_color_theme("dark-blue") root = customtkinter.CTk() root.title("GVA - GUI") root.geometry("600x400") nm = nmap.PortScanner() model_engine = "text-davinci-003" def application() -> None: try: apikey = entry1.get() openai.api_key = apikey target = entry2.get() attack = entry5.get() outputf = str(entry4.get()) match attack: case 'geo': val = geoip(apikey, target) print(val) output_save(val, outputf) case "nmap": p = int(entry3.get()) match p: case 1: val = scanner(target, 1, apikey) print(val) output_save(val, outputf) case 2: val = scanner(target, 2, apikey) print(val) output_save(val, outputf) case 3: val = scanner(target, 3, apikey) print(val) output_save(val, outputf) case 4: val = scanner(target, 4, apikey) print(val) output_save(val, outputf) case 5: val = scanner(target, 5, apikey) print(val) output_save(val, outputf) case "dns": val = dns_recon(target, apikey) output_save(val, outputf) case "subd": val = sub(target) output_save(val, outputf) except KeyboardInterrupt: print("Keyboard Interrupt detected ...") def dns_extract_data(json_string: str) -> Any: # Define the regular expression patterns for individual values A_pattern = r'"A": \["(.*?)"\]' AAA_pattern = r'"AAA: \["(.*?)"\]' NS_pattern = r'"NS": \["(.*?)"\]' MX_pattern = r'"MX": \["(.*?)"\]' PTR_pattern = r'"PTR": \["(.*?)"\]' SOA_pattern = r'"SOA": \["(.*?)"\]' TXT_pattern = r'"TXT": \["(.*?)"\]' # Initialize variables for extracted data A = None AAA = None NS = None MX = None PTR = None SOA = None TXT = None # Extract individual values using patterns match = re.search(A_pattern, json_string) if match: A = match.group(1) match = re.search(AAA_pattern, json_string) if match: AAA = match.group(1) match = re.search(NS_pattern, json_string) if match: NS = match.group(1) match = re.search(MX_pattern, json_string) if match: MX = match.group(1) match = re.search(PTR_pattern, json_string) if match: PTR = match.group(1) match = re.search(SOA_pattern, json_string) if match: SOA = match.group(1) match = re.search(TXT_pattern, json_string) if match: TXT = match.group(1) # Create a dictionary to store the extracted data data = { "A": A, "AAA": AAA, "NS": NS, "MX": MX, "PTR": PTR, "SOA": SOA, "TXT": TXT } # Convert the dictionary to JSON format json_output = json.dumps(data) return json_output def port_extract_data(json_string: str) -> Any: # Define the regular expression patterns for individual values critical_score_pattern = r'"critical score": \["(.*?)"\]' os_information_pattern = r'"os information": \["(.*?)"\]' open_ports_pattern = r'"open ports": \["(.*?)"\]' open_services_pattern = r'"open services": \["(.*?)"\]' vulnerable_service_pattern = r'"vulnerable service": \["(.*?)"\]' found_cve_pattern = r'"found cve": \["(.*?)"\]' # Initialize variables for extracted data critical_score = None os_information = None open_ports = None open_services = None vulnerable_service = None found_cve = None # Extract individual values using patterns match = re.search(critical_score_pattern, json_string) if match: critical_score = match.group(1) match = re.search(os_information_pattern, json_string) if match: os_information = match.group(1) match = re.search(open_ports_pattern, json_string) if match: open_ports = match.group(1) match = re.search(open_services_pattern, json_string) if match: open_services = match.group(1) match = re.search(vulnerable_service_pattern, json_string) if match: vulnerable_service = match.group(1) match = re.search(found_cve_pattern, json_string) if match: found_cve = match.group(1) # Create a dictionary to store the extracted data data = { "critical score": critical_score, "os information": os_information, "open ports": open_ports, "open services": open_services, "vulnerable service": vulnerable_service, "found cve": found_cve } # Convert the dictionary to JSON format json_output = json.dumps(data) return json_output def DnsAI(analyze: str, key: Optional[str]) -> str: openai.api_key = key prompt = f""" Do a DNS analysis on the provided DNS scan information The DNS output must return in a JSON format accorging to the provided output format. The data must be accurate in regards towards a pentest report. The data must follow the following rules: 1) The DNS scans must be done from a pentester point of view 2) The final output must be minimal according to the format given 3) The final output must be kept to a minimal The output format: {{ "A": [""], "AAA": [""], "NS": [""], "MX": [""], "PTR": [""], "SOA": [""], "TXT": [""] }} DNS Data to be analyzed: {analyze} """ try: # A structure for the request completion = openai.Completion.create( engine=model_engine, prompt=prompt, max_tokens=1024, n=1, stop=None, ) response = completion.choices[0].text return dns_extract_data(str(response)) except KeyboardInterrupt: print("Bye") quit() def PortAI(key: str, data: Any) -> str: openai.api_key = key try: prompt = f""" Do a NMAP scan analysis on the provided NMAP scan information The NMAP output must return in a JSON format accorging to the provided output format. The data must be accurate in regards towards a pentest report. The data must follow the following rules: 1) The NMAP scans must be done from a pentester point of view 2) The final output must be minimal according to the format given. 3) The final output must be kept to a minimal. 4) If a value not found in the scan just mention an empty string. 5) Analyze everything even the smallest of data. The output format: {{ "critical score": [""], "os information": [""], "open ports": [""], "open services": [""], "vulnerable service": [""], "found cve": [""] }} NMAP Data to be analyzed: {data} """ # A structure for the request completion = openai.Completion.create( engine=model_engine, prompt=prompt, max_tokens=1024, n=1, stop=None, ) response = completion.choices[0].text return port_extract_data(str(response)) except KeyboardInterrupt: print("Bye") quit() def geoip(key: Optional[str], target: str) -> Any: if key is None: raise ValueError("KeyNotFound: Key Not Provided") assert key is not None # This will help the type checker if target is None: raise ValueError("InvalidTarget: Target Not Provided") url = f"https://api.ipgeolocation.io/ipgeo?apiKey={key}&ip={target}" response = requests.get(url) content = response.text return content def output_save(output: Any, outf: Any) -> Any: top = customtkinter.CTkToplevel(root) top.title("GVA Output") top.grid_rowconfigure(0, weight=1) top.grid_columnconfigure(0, weight=1) top.textbox = customtkinter.CTkTextbox( master=top, height=500, width=400, corner_radius=0) top.textbox.grid(row=0, column=0, sticky="nsew") try: file = open(outf, 'x') except FileExistsError: file = open(outf, "r+") file.write(str(output)) file.close top.textbox.insert("0.0", text=output) def sub(target: str) -> Any: s_array = ['www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'hod', 'butterfly', 'ckp', 'tele2', 'receiver', 'reality', 'panopto', 't7', 'thot', 'wien', 'uat-online', 'Footer'] ss = [] out = "" for subd in s_array: try: ip_value = dns.resolver.resolve(f'{subd}.{target}', 'A') if ip_value: ss.append(f'{subd}.{target}') if f"{subd}.{target}" in ss: print(f'{subd}.{target} | Found') out += f'{subd}.{target}' out += "\n" out += "" else: pass except dns.resolver.NXDOMAIN: pass except dns.resolver.NoAnswer: pass except KeyboardInterrupt: print('Ended') quit() return out def dns_recon(target: Optional[str], key: str) -> str: if key is not None: pass else: raise ValueError("KeyNotFound: Key Not Provided") if target is not None: pass else: raise ValueError("InvalidTarget: Target Not Provided") analyze = '' # The DNS Records to be enumeratee record_types = ['A', 'AAAA', 'NS', 'CNAME', 'MX', 'PTR', 'SOA', 'TXT'] for records in track(record_types): try: answer = dns.resolver.resolve(target, records) for server in answer: st = server.to_text() analyze += "\n" analyze += records analyze += " : " analyze += st except dns.resolver.NoAnswer: print('No record Found') pass except dns.resolver.NXDOMAIN: print('NXDOMAIN record NOT Found') pass except KeyboardInterrupt: print("Bye") quit() try: response = DnsAI(key, analyze) return str(response) except KeyboardInterrupt: print("Bye") quit() def scanner(ip: Optional[str], profile: int, key: str) -> str: if key is not None: pass else: raise ValueError("KeyNotFound: Key Not Provided") # Handle the None case profile_argument = "" # The port profiles or scan types user can choose if profile == 1: profile_argument = '-Pn -sV -T4 -O -F' elif profile == 2: profile_argument = '-Pn -T4 -A -v' elif profile == 3: profile_argument = '-Pn -sS -sU -T4 -A -v' elif profile == 4: profile_argument = '-Pn -p- -T4 -A -v' elif profile == 5: profile_argument = '-Pn -sS -sU -T4 -A -PE -PP -PS80,443 -PA3389 -PU40125 -PY -g 53 --script=vuln' else: raise ValueError(f"Invalid Argument: {profile}") # The scanner with GPT Implemented nm.scan('{}'.format(ip), arguments='{}'.format(profile_argument)) json_data = nm.analyse_nmap_xml_scan() analyze = json_data["scan"] try: response = PortAI(key, analyze) except KeyboardInterrupt: print("Bye") quit() return str(response) frame = customtkinter.CTkFrame(master=root) frame.pack(pady=20, padx=60, fill="both", expand=True) label = customtkinter.CTkLabel( master=frame, text="GVA System") label.pack(pady=12, padx=10) entry1 = customtkinter.CTkEntry(master=frame, placeholder_text="API_KEY") entry1.pack(pady=12, padx=10) entry2 = customtkinter.CTkEntry(master=frame, placeholder_text="Target") entry2.pack(pady=12, padx=10) entry5 = customtkinter.CTkEntry( master=frame, placeholder_text="Attack (nmap/dns)") entry5.pack(pady=12, padx=10) entry4 = customtkinter.CTkEntry(master=frame, placeholder_text="Savefile.json") entry4.pack(pady=12, padx=10) entry3 = customtkinter.CTkEntry( master=frame, placeholder_text="Profile (Only Nmap)") entry3.pack(pady=12, padx=10) radiobutton_var = customtkinter.IntVar(value=1) button = customtkinter.CTkButton( master=frame, text="Run", command=application) button.pack(pady=12, padx=10) root.mainloop()