Spaces:
Sleeping
Sleeping
| 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() | |