From 883b7dc6d49144d40d70bb032edcaa404ee7c99d Mon Sep 17 00:00:00 2001 From: blahberi Date: Tue, 19 May 2020 16:01:24 +0300 Subject: [PATCH] did stuff --- Clients/Client.py | 3 + Clients/VTClient.py | 86 +++++++++++++++++++ {VTPackage => Clients}/__init__.py | 0 Clients/shodanClient.py | 14 +++ Main.py | 4 +- UI/Consts.py | 1 + UI/FileReportTab.py | 131 +++++++++++++++++++++++++++++ UI/IPreportTab.py | 82 ++++++++++++++++++ UI/PasswordGeneraorTab.py | 98 +++++++++++++++++++++ UI/PasswordStreangthTab.py | 130 ++++++++++++++++++++++++++++ UI/ProportiesTab.py | 50 +++++++++++ {VTPackage => UI}/URLreportTab.py | 34 ++++++-- UI/VTApp.py | 70 +++++++++++++++ UI/__init__.py | 0 VTPackage/VTApp.py | 35 -------- VTPackage/VTClient.py | 22 ----- conig.ini | 6 ++ transparent.ico | Bin 0 -> 1406 bytes 18 files changed, 699 insertions(+), 67 deletions(-) create mode 100644 Clients/Client.py create mode 100644 Clients/VTClient.py rename {VTPackage => Clients}/__init__.py (100%) create mode 100644 Clients/shodanClient.py create mode 100644 UI/Consts.py create mode 100644 UI/FileReportTab.py create mode 100644 UI/IPreportTab.py create mode 100644 UI/PasswordGeneraorTab.py create mode 100644 UI/PasswordStreangthTab.py create mode 100644 UI/ProportiesTab.py rename {VTPackage => UI}/URLreportTab.py (61%) create mode 100644 UI/VTApp.py create mode 100644 UI/__init__.py delete mode 100644 VTPackage/VTApp.py delete mode 100644 VTPackage/VTClient.py create mode 100644 conig.ini create mode 100644 transparent.ico diff --git a/Clients/Client.py b/Clients/Client.py new file mode 100644 index 0000000..fba811a --- /dev/null +++ b/Clients/Client.py @@ -0,0 +1,3 @@ +class Client: + def __init__(self, apiKey): + self.apiKey = apiKey \ No newline at end of file diff --git a/Clients/VTClient.py b/Clients/VTClient.py new file mode 100644 index 0000000..2034734 --- /dev/null +++ b/Clients/VTClient.py @@ -0,0 +1,86 @@ +import requests +from Clients.Client import Client + +class VTClient(Client): + def __init__(self, apiKey): + super().__init__(apiKey) + self.baseURL = 'https://www.virustotal.com/vtapi/v2/' + + def get_url_report(self,URL): + try: + requestURL = f'{self.baseURL}url/report?apikey={self.apiKey}&resource={URL}/' + payload = {} + headers = {} + response = requests.request("GET", requestURL, headers=headers, data=payload) + if response.status_code == 204: + raise Exception("To much API requests") + info = response.json() + if info["response_code"] == 0: + raise Exception(info["verbose_msg"]) + return info + + except Exception as e: + print(e) + raise Exception(e) + + + def get_ip_report(self,IP): + try: + requestURL = f'{self.baseURL}ip-address/report?apikey={self.apiKey}&ip={IP}' + payload = {} + headers = {} + response = requests.request("GET", requestURL, headers=headers, data=payload) + if response.status_code == 403: + return 'invalid api' + result = response.json() + if response.status_code == 204: + raise Exception("To much API requests") + info = response.json() + if info["response_code"] == 0: + raise Exception(info["verbose_msg"]) + return info + + except Exception as e: + print(e) + raise Exception(e) + + def scan_file(self, filePath): + try: + url = f'{self.baseURL}file/scan' + + params = {'apikey': self.apiKey} + + files = {'file': (filePath, open(filePath, 'rb'))} + + response = requests.post(url, files=files, params=params) + info = response.json() + if info['response_code'] == 204: + print("to many api requests") + if info["response_code"] == 1: + return info["scan_id"] + else: + raise Exception("error") + except Exception as e: + raise e + + def get_file_report(self, scan_id): + url = f'{self.baseURL}file/report' + + params = {'apikey': self.apiKey, 'resource': scan_id} + response = requests.get(url, params=params) + info = response.json() + if 'positives' in info: + if response.status_code == 204: + raise Exception("to many api requests") + return False + elif response.status_code == 200: + return info + elif response.status_code == 403: + raise Exception("this api key is forbiden. try again later") + return False + elif response.status_code == 404: + return False + else: + return False + else: + return False \ No newline at end of file diff --git a/VTPackage/__init__.py b/Clients/__init__.py similarity index 100% rename from VTPackage/__init__.py rename to Clients/__init__.py diff --git a/Clients/shodanClient.py b/Clients/shodanClient.py new file mode 100644 index 0000000..ce6f82b --- /dev/null +++ b/Clients/shodanClient.py @@ -0,0 +1,14 @@ +from Clients.Client import Client +import shodan + +class shodanClient(Client): + def __init__(self, apiKey): + super().__init__(apiKey) + self.api = shodan.Shodan(apiKey) + + + def get_ip_report(self, IP): + # Search Shodan + response = self.api.host(IP) + print(response) + return response \ No newline at end of file diff --git a/Main.py b/Main.py index 32b0c3d..f2a905b 100644 --- a/Main.py +++ b/Main.py @@ -1,4 +1,4 @@ -from VTPackage import VTApp +from UI.VTApp import VTApp -vtApp = VTApp.VTApp() +vtApp = VTApp() vtApp.start() \ No newline at end of file diff --git a/UI/Consts.py b/UI/Consts.py new file mode 100644 index 0000000..0eaf81b --- /dev/null +++ b/UI/Consts.py @@ -0,0 +1 @@ +ENTRY_WIDTH = 40 \ No newline at end of file diff --git a/UI/FileReportTab.py b/UI/FileReportTab.py new file mode 100644 index 0000000..743a351 --- /dev/null +++ b/UI/FileReportTab.py @@ -0,0 +1,131 @@ +from tkinter import ttk +from tkinter import StringVar +from UI import Consts +from tkinter import filedialog +from tkinter import messagebox +import time + + +class FileReportTab: + + def __init__(self, root, frame, vtClient): + self.root = root + self.frame = frame + self.vtClient = vtClient + + self.mainVTURLframe = ttk.LabelFrame(frame, text='File report') + self.mainVTURLframe.grid(column=0, row=1, padx=8, pady=4) + + ttk.Label(self.mainVTURLframe, text="Progress:").grid(column=0, row=1, sticky='W') # <== right-align + self.progressBar = ttk.Progressbar(self.mainVTURLframe, orient='horizontal', length=300, mode='determinate') + self.progressBar.grid(column=1, row=1) + + ttk.Label(self.mainVTURLframe, text="File path:").grid(column=0, row=2, sticky='W') # <== right-align + self.filePath = StringVar() + filePathEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.filePath, state='readonly') + filePathEntry.grid(column=1, row=2, sticky='W') + + ttk.Label(self.mainVTURLframe, text="Status:").grid(column=0, row=3, sticky='W') # <== right-align + self.status = StringVar() + statusEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.status, state='readonly') + statusEntry.grid(column=1, row=3, sticky='W') + + ttk.Label(self.mainVTURLframe, text="Positive Indications:").grid(column=0, row=4, sticky='W') # <== right-align + self.positiveIndications = StringVar() + positiveIndicationsEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.positiveIndications, state='readonly') + positiveIndicationsEntry.grid(column=1, row=4, sticky='W') + + ttk.Label(self.mainVTURLframe, text="SHA1:").grid(column=0, row=5, sticky='W') # <== right-align + self.sha1 = StringVar() + sha1Entry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.sha1, state='readonly') + sha1Entry.grid(column=1, row=5, sticky='W') + + ttk.Label(self.mainVTURLframe, text="SHA256:").grid(column=0, row=6, sticky='W') # <== right-align + self.sha256 = StringVar() + sha256Entry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.sha256, + state='readonly') + sha256Entry.grid(column=1, row=6, sticky='W') + + chooseFileButton = ttk.Button(self.mainVTURLframe, text="Choose File", width=40, command=self.show_file_report).grid( + column=1, row=0) + + self.scanCheckingTimeInterval = 25000 # This is the amount of time we are going to wait before asking VT again if it already processed our scan request + + for child in self.mainVTURLframe.winfo_children(): + child.grid_configure(padx=4, pady=2) + + + def move_progressbar(self, amount = 100): + previousAmount = self.progressBar['value'] + for i in range(amount - int(previousAmount)): + self.progressBar['value'] = previousAmount + i + 1 + time.sleep(0.05) + self.progressBar.update() + + + def _scanFile(self): + try: + self.progressBar['value'] = 0 + filePath = filedialog.askopenfilename(initialdir="/", title="Select file to scan", + filetypes=(('All files', "*"), + ('EXE files', "*.exe"), + ("Jar files", "*.jar"))) + self.move_progressbar(25) + + if (filePath): + self.filePath.set(filePath) + self.status.set('scaning file') + self.scanID = self.vtClient.scan_file(filePath) + self.move_progressbar(50) + for t in range(3): + t = t + 1 + self.scanResult = self.vtClient.get_file_report(self.scanID) + if self.scanResult != False: + self.move_progressbar(100) + self.status.set("scan finished") + print('scan has finished') + return self.scanResult + else: + self.move_progressbar(50 + 16 * t) + print('scan not finished') + time.sleep(10) + print('scan failed') + return False + self.root.lift() + messagebox.showerror(title = "no file", message = 'this is not a file. \n please choose a valid file') + + + + except Exception as e: + self.root.lift() + messagebox.showerror(title = "Error", message = "an error occurred while scanning this file. \n try again") + raise e + return False + pass + + + def checkStatus(self): + try: + print("checking") + self.scanResult = self.vtClient.get_file_report(self.scanID) + + if self.scanResult["response_code"] == -2: + self.status.set("scanning...") + self.progressBar['value'] = self.progressBar['value'] + 5 + else: + self.hasScanFinished = True + self.sha1.set(self.scanResult["sha1"]) + self.sha256.set(self.scanResult["sha256"]) + + except Exception as e: + pass + def show_file_report(self): + fileReport = self._scanFile() + if fileReport == False: + self.status.set("scan failed") + return + self.positiveIndications.set(fileReport['positives']) + self.sha1.set(fileReport['sha1']) + self.sha256.set(fileReport['sha256']) + + diff --git a/UI/IPreportTab.py b/UI/IPreportTab.py new file mode 100644 index 0000000..d7afcb3 --- /dev/null +++ b/UI/IPreportTab.py @@ -0,0 +1,82 @@ +from tkinter import ttk +from tkinter import StringVar + +ENTRY_WIDTH = 40 + +class IPreportTab: + def __init__(self, root, frame, clients): + self.vtClient = clients[0] + self.shodanClient = clients[1] + self.root = root + self.frame = frame + self.mainVTIPFrame = ttk.Labelframe(frame, text = 'IP report tab') + + + self.mainVTIPFrame.grid(column = 0, row = 0, padx = 8, pady = 4) + ttk.Label(self.mainVTIPFrame, text = "IP:").grid(column = 0, row = 0, sticky = "W") + ipEntry = ttk.Entry(self.mainVTIPFrame) + ipEntry.grid(column = 1, row = 0, sticky = "E") + + + ttk.Label(self.mainVTIPFrame, text = "Country:").grid(column = 0, row = 1, sticky = "W") + Country = StringVar() + ttk.Entry(self.mainVTIPFrame, textvariable = Country, state = 'readonly').grid(column = 1, row = 1, sticky = "E") + + + ttk.Label(self.mainVTIPFrame, text = "Owner:").grid(column = 0, row = 2, sticky = "W") + Owner = StringVar() + ttk.Entry(self.mainVTIPFrame, textvariable = Owner, state = 'readonly').grid(column = 1, row = 2, sticky = "E") + + + ttk.Label(self.mainVTIPFrame, text = "Number of detected URLS:").grid(column = 0, row = 3, sticky = "W") + NumberOfDetectedURLS = StringVar() + ttk.Entry(self.mainVTIPFrame, textvariable = NumberOfDetectedURLS, state = 'readonly').grid(column = 1, row = 3, sticky = "E") + + + ttk.Label(self.mainVTIPFrame, text = "Number of detected malicious files:").grid(column = 0, row = 4, sticky = "W") + NumberOfDetectedMaliciousFiles = StringVar() + ttk.Entry(self.mainVTIPFrame, textvariable = NumberOfDetectedMaliciousFiles, state = 'readonly').grid(column = 1, row = 4, sticky = "E") + + + ttk.Label(self.mainVTIPFrame, text = "open ports").grid(column = 0, row = 5, sticky = "W") + ports = StringVar() + ttk.Entry(self.mainVTIPFrame, textvariable = ports, state = 'readonly').grid(column = 1, row = 5, sticky = "E") + + + notificationFrame = ttk.LabelFrame(self.frame, text=' Notifications', width=40) + # using the tkinter grid layout manager + notificationFrame.grid(column=0, row=1, padx=8, pady=10, sticky='W') + + + ttk.Label(notificationFrame, text="Errors:").grid(column=0, row=0, sticky='W') # <== increment row for each + Error = StringVar() + ErrorEntry = ttk.Entry(notificationFrame, width=ENTRY_WIDTH, textvariable=Error, state='readonly') + ErrorEntry.grid(column=1, row=0, sticky='W') + + def CleanErrorMessage(): + Error.set('') + + + def print_ip_report(): + try: + CleanErrorMessage() # Starting with cleaning the error message bar + if not ipEntry.get(): + print('Please enter a IP') + Error.set("Please enter a IP!") + return + + ipToCheck = ipEntry.get() + VTresponse = self.vtClient.get_ip_report(ipToCheck) + SHODANresponse = self.shodanClient.get_ip_report(ipToCheck) + print(VTresponse) + Country.set(VTresponse["country"]) + Owner.set(VTresponse["as_owner"]) + NumberOfDetectedURLS.set(len(VTresponse["detected_urls"])) + NumberOfDetectedMaliciousFiles.set(len(VTresponse["detected_downloaded_samples"])) + ports.set(SHODANresponse["ports"]) + + + except Exception as e: + raise e + Error.set(e) + ttk.Button(self.mainVTIPFrame, text = "Check in VT", command = print_ip_report).grid(column = 2, row = 0, sticky = "E") \ No newline at end of file diff --git a/UI/PasswordGeneraorTab.py b/UI/PasswordGeneraorTab.py new file mode 100644 index 0000000..0ac0bb5 --- /dev/null +++ b/UI/PasswordGeneraorTab.py @@ -0,0 +1,98 @@ +import random +import tkinter +import tkinter as tk +from tkinter import ttk +import os +from UI import Consts +from tkinter import Menu + +class PasswordGeneratorTab: + + def __init__(self, root, frame): + self.root = root + self.frame = frame + self.minlength = 16 + self.maxlength = 20 + self.minASCII = 65 + self.maxASCII = 90 + self.minDigetASCII = 48 + self.maxDigetASCII = 57 + self.ENTRY_WIDTH = 40 + + + self.generateFrame = ttk.Labelframe(frame, text='generate password') + self.generateFrame.grid(column=0, row=1, padx=8, pady=10, sticky="W") + + + ttk.Label(self.generateFrame, text="password min size:").grid(column=0, row=0, padx=0, pady=0, sticky="W") + + self.minSize = tk.StringVar() + self.minSizeEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.minSize) + self.minSizeEntry.grid(column=1, row=0, sticky="W") + self.minSize.set(str(self.minlength)) + + ttk.Label(self.generateFrame, text="password max size:").grid(column=0, row=1, padx=0, pady=0, sticky="W") + + self.maxSize = tk.StringVar() + self.maxSizeEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.maxSize) + self.maxSizeEntry.grid(column=1, row=1, sticky="W") + self.maxSize.set(str(self.maxlength)) + + ttk.Button(self.generateFrame, text="generate", command=self.show_passwword).grid(column=1, row=2) + + ttk.Label(self.generateFrame, text="password min size:").grid(column=0, row=3, padx=0, pady=0, sticky="W") + + self.PasswordVar = tk.StringVar() + self.passwordEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.PasswordVar, state='readonly') + self.passwordEntry.grid(column=1, row=3, sticky="W") + + self.photo = tkinter.PhotoImage(file=r'C:\Users\\eitan\PycharmProjects\passwordGenerator\copy.png') + + ttk.Button(self.generateFrame, image=self.photo, command=self.copy).grid(column=2, row=3) + + + def generate_password(self, passLength): + generatedpassword = '' + password = "" + for character in range(passLength): + if random.randint(1, 3) == 1: + char = chr(random.randint(self.minDigetASCII, self.maxDigetASCII)) + generatedpassword += char + else: + char = chr(random.randint(self.minASCII, self.maxASCII)) + generatedpassword += char.lower() + for char in generatedpassword: + if char.isdigit() == False: + if random.randint(1, 3) == 3: + password += char.upper() + else: + password += char + else: + password += char + return password + + + def addToClipBoard(self, text): + command = 'echo ' + text.strip() + '| clip' + os.system(command) + + + def show_passwword(self): + try: + minlength = int(self.minSize.get()) + maxlength = int(self.maxSize.get()) + + passleangth = random.randint(minlength, maxlength) + + password = self.generate_password(passleangth) + + self.PasswordVar.set(password) + + except: + raise Exception + print('there was an error when generating passowrd \n' + 'are you sure that password min size or max size are actually numbers \n' + 'or min size is smaller than max size') + + def copy(self): + self.addToClipBoard(self.PasswordVar.get()) \ No newline at end of file diff --git a/UI/PasswordStreangthTab.py b/UI/PasswordStreangthTab.py new file mode 100644 index 0000000..5b1a0d9 --- /dev/null +++ b/UI/PasswordStreangthTab.py @@ -0,0 +1,130 @@ +from tkinter import ttk +from tkinter import StringVar +from UI import Consts +from tkinter import filedialog +from tkinter import messagebox +import time + + +class FileReportTab: + + def __init__(self, root, frame): + self.root = root + self.frame = frame + + self.generateFrame = ttk.LabelFrame(frame, text='File report') + self.generateFrame.grid(column=0, row=1, padx=8, pady=4) + + ttk.Label(self.generateFrame, text="Progress:").grid(column=0, row=1, sticky='W') # <== right-align + self.progressBar = ttk.Progressbar(self.generateFrame, orient='horizontal', length=300, mode='determinate') + self.progressBar.grid(column=1, row=1) + + ttk.Label(self.generateFrame, text="File path:").grid(column=0, row=2, sticky='W') # <== right-align + self.filePath = StringVar() + filePathEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.filePath, state='readonly') + filePathEntry.grid(column=1, row=2, sticky='W') + + ttk.Label(self.generateFrame, text="Status:").grid(column=0, row=3, sticky='W') # <== right-align + self.status = StringVar() + statusEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.status, state='readonly') + statusEntry.grid(column=1, row=3, sticky='W') + + ttk.Label(self.generateFrame, text="Positive Indications:").grid(column=0, row=4, sticky='W') # <== right-align + self.positiveIndications = StringVar() + positiveIndicationsEntry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.positiveIndications, state='readonly') + positiveIndicationsEntry.grid(column=1, row=4, sticky='W') + + ttk.Label(self.generateFrame, text="SHA1:").grid(column=0, row=5, sticky='W') # <== right-align + self.sha1 = StringVar() + sha1Entry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.sha1, state='readonly') + sha1Entry.grid(column=1, row=5, sticky='W') + + ttk.Label(self.generateFrame, text="SHA256:").grid(column=0, row=6, sticky='W') # <== right-align + self.sha256 = StringVar() + sha256Entry = ttk.Entry(self.generateFrame, width=Consts.ENTRY_WIDTH, textvariable=self.sha256, + state='readonly') + sha256Entry.grid(column=1, row=6, sticky='W') + + chooseFileButton = ttk.Button(self.generateFrame, text="Choose File", width=40, command=self.show_file_report).grid( + column=1, row=0) + + self.scanCheckingTimeInterval = 25000 # This is the amount of time we are going to wait before asking VT again if it already processed our scan request + + for child in self.generateFrame.winfo_children(): + child.grid_configure(padx=4, pady=2) + + + def move_progressbar(self, amount = 100): + previousAmount = self.progressBar['value'] + for i in range(amount - int(previousAmount)): + self.progressBar['value'] = previousAmount + i + 1 + time.sleep(0.05) + self.progressBar.update() + + + def _scanFile(self): + try: + self.progressBar['value'] = 0 + filePath = filedialog.askopenfilename(initialdir="/", title="Select file to scan", + filetypes=(('All files', "*"), + ('EXE files', "*.exe"), + ("Jar files", "*.jar"))) + self.move_progressbar(25) + + if (filePath): + self.filePath.set(filePath) + self.status.set('scaning file') + self.scanID = self.vtClient.scan_file(filePath) + self.move_progressbar(50) + for t in range(3): + t = t + 1 + self.scanResult = self.vtClient.get_file_report(self.scanID) + if self.scanResult != False: + self.move_progressbar(100) + self.status.set("scan finished") + print('scan has finished') + return self.scanResult + else: + self.move_progressbar(50 + 16 * t) + print('scan not finished') + time.sleep(10) + print('scan failed') + return False + self.root.lift() + messagebox.showerror(title = "no file", message = 'this is not a file. \n please choose a valid file') + + + + except Exception as e: + self.root.lift() + messagebox.showerror(title = "Error", message = "an error occurred while scanning this file. \n try again") + raise e + return False + pass + + + def checkStatus(self): + try: + print("checking") + self.scanResult = self.vtClient.get_file_report(self.scanID) + + if self.scanResult["response_code"] == -2: + self.status.set("scanning...") + self.progressBar['value'] = self.progressBar['value'] + 5 + else: + self.hasScanFinished = True + self.sha1.set(self.scanResult["sha1"]) + self.sha256.set(self.scanResult["sha256"]) + + except Exception as e: + pass + def show_file_report(self): + fileReport = self._scanFile() + if fileReport == False: + self.status.set("scan failed") + return + self.positiveIndications.set(fileReport['positives']) + self.sha1.set(fileReport['sha1']) + self.sha256.set(fileReport['sha256']) + + diff --git a/UI/ProportiesTab.py b/UI/ProportiesTab.py new file mode 100644 index 0000000..57cc8e5 --- /dev/null +++ b/UI/ProportiesTab.py @@ -0,0 +1,50 @@ +from tkinter import ttk +from UI import Consts +import configparser +from pathlib import Path +from Clients.VTClient import VTClient +from Clients.shodanClient import shodanClient +config = configparser.ConfigParser() +configfile = Path(r'C:\Users\eitan\PycharmProjects\virusTotal-ui-python\conig.ini') +config.read(configfile) + +class ProportiesTab: + + def __init__(self, root, frame): + self.root = root + self.frame = frame + self.vtClient = VTClient(config['VirusTotal']['apiKey']) + self.shodanClient = shodanClient(config['Shodan']['apiKey']) + + self.proportiesFrame = ttk.LabelFrame(frame, text='Proporties') + self.proportiesFrame.grid(column=0, row=1, padx=8, pady=4) + + ttk.Label(self.proportiesFrame, text="virus total apikey:").grid(column=0, row=2, sticky='W') # <== right-align + vtApiKeyEntry = ttk.Entry(self.proportiesFrame, width=Consts.ENTRY_WIDTH) + vtApiKeyEntry.grid(column=1, row=2, sticky='W') + vtApiKeyEntry.insert(0, config.get('VirusTotal', 'apiKey')) + + + ttk.Label(self.proportiesFrame, text="shodan apikey:").grid(column=0, row=3, sticky='W') # <== right-align + shodanApiKeyEntry = ttk.Entry(self.proportiesFrame, width=Consts.ENTRY_WIDTH) + shodanApiKeyEntry.grid(column=1, row=3, sticky='W') + shodanApiKeyEntry.insert(0, config.get('Shodan', 'apiKey')) + + def Save(): + config.set('VirusTotal', 'apiKey', str(vtApiKeyEntry.get())) + config.set('Shodan', 'apiKey', str(shodanApiKeyEntry.get())) + config.write(configfile.open('w')) + + + if self.vtClient.get_ip_report(IP = '8.8.8.8') == 'invalid api': + print('invalid VT api key') + try: + self.shodanClient.get_ip_report(IP = '8.8.8.8') + except: + if Exception == "Invalid API key": + print('invalid shodan api key') + + + + + saveButton = ttk.Button(self.proportiesFrame, text='Save', command=Save).grid(column=1, row=4) diff --git a/VTPackage/URLreportTab.py b/UI/URLreportTab.py similarity index 61% rename from VTPackage/URLreportTab.py rename to UI/URLreportTab.py index ec54e7c..d3bb847 100644 --- a/VTPackage/URLreportTab.py +++ b/UI/URLreportTab.py @@ -1,6 +1,7 @@ from tkinter import ttk from tkinter import StringVar +ENTRY_WIDTH = 40 class URLreportTab: def __init__(self,root,frame, vtClient): self.root = root @@ -11,20 +12,20 @@ def __init__(self,root,frame, vtClient): # using the tkinter grid layout manager self.mainVTURLframe.grid(column=0, row=0, padx=8, pady=4) ttk.Label(self.mainVTURLframe, text="URL:").grid(column=0, row=0, sticky='W') #What does sticky does? Sticky sayes where to stick the label to : N,S,E,W - urlEntry = ttk.Entry(self.mainVTURLframe) + urlEntry = ttk.Entry(self.mainVTURLframe, width = ENTRY_WIDTH) urlEntry.grid(column=1, row=0, sticky='E') - ttk.Label(self.mainVTURLframe, text="URL:").grid(column=0, row=0, sticky='W') - urlEntry = ttk.Entry(self.mainVTURLframe) - urlEntry.grid(column=1, row=0, sticky='E') ttk.Label(self.mainVTURLframe, text="Positive Indications:").grid(column=0, row=1, sticky='W') # <== right-align Positive = StringVar() - PositiveEntry = ttk.Entry(self.mainVTURLframe, width=20, textvariable=Positive, state='readonly') + PositiveEntry = ttk.Entry(self.mainVTURLframe, width=ENTRY_WIDTH, textvariable=Positive, state='readonly') PositiveEntry.grid(column=1, row=1, sticky='W') - - + # using the tkinter grid layout manager + ttk.Label(self.mainVTURLframe, text="Positive detections:").grid(column=0, row=2, sticky='W') # <== right-align + detections = StringVar() + DetectionsEntry = ttk.Entry(self.mainVTURLframe, width=ENTRY_WIDTH, textvariable=detections, state='readonly') + DetectionsEntry.grid(column=1, row=2, sticky='W') notificationFrame = ttk.LabelFrame(self.frame, text=' Notifications', width=40) # using the tkinter grid layout manager @@ -32,9 +33,12 @@ def __init__(self,root,frame, vtClient): ttk.Label(notificationFrame, text="Errors:").grid(column=0, row=0, sticky='W') # <== increment row for each Error = StringVar() - ErrorEntry = ttk.Entry(notificationFrame, width=20, textvariable=Error, state='readonly') + ErrorEntry = ttk.Entry(notificationFrame, width=ENTRY_WIDTH, textvariable=Error, state='readonly') ErrorEntry.grid(column=1, row=0, sticky='W') + + ###positive errors frame + def cleanErrorMessage(): # We could have been doing this without a function, but it is more neat that way Error.set("") @@ -52,6 +56,20 @@ def getReport(): print(response) Positive.set(response["positives"]) scans = response["scans"] + findings = set() + for antiVirusName, antiVirusResult in scans.items(): + if antiVirusResult["detected"] == True: + findings.add(antiVirusResult["result"]) + s = ", " + detections.set(s.join(findings)) + + + + # positivesDetections = [] + # for detection in response["scans":"detected"]: + # if detections["true"]: + # positivesDetections.append(detections["result"]) + # print(positivesDetections) except Exception as e: diff --git a/UI/VTApp.py b/UI/VTApp.py new file mode 100644 index 0000000..65f077d --- /dev/null +++ b/UI/VTApp.py @@ -0,0 +1,70 @@ +import tkinter as tk +from tkinter import Menu +from tkinter import ttk +from UI import FileReportTab, IPreportTab, URLreportTab, ProportiesTab, PasswordGeneraorTab +from Clients import VTClient +from Clients import shodanClient +import configparser +config = configparser.ConfigParser() +config.read(r'C:\Users\eitan\PycharmProjects\virusTotal-ui-python\conig.ini') + +vtCongig = config['VirusTotal'] +vtTOKEN = vtCongig['apiKey'] + +shodanConfig = config['Shodan'] +shodanTOKEN = shodanConfig['apiKey'] + +class VTApp: + def __init__(self): + self.clients = [VTClient.VTClient(vtTOKEN), shodanClient.shodanClient(shodanTOKEN)] + self.root = tk.Tk() + self.root.iconbitmap(r"C:\Users\eitan\PycharmProjects\virusTotal-ui-python\transparent.ico") + self.root.title("VT App") + self.menuBar = Menu() + self.root.config(menu=self.menuBar) + self.fileMenu = Menu(self.menuBar, tearoff=0) + self.fileMenu.add_command(label="New") + self.fileMenu.add_separator() + self.menuBar.add_cascade(label="File", menu=self.fileMenu) + + def _quit(): + self.root.quit() # win will exist when this function is called + self.root.destroy() + exit() + + self.fileMenu.add_command(label="Exit", command=_quit) # command callback + self.tabControl = ttk.Notebook(self.root) # Create Tab Control + + + self.proportiesFrame = ttk.Frame(self.tabControl) + self.proportiesTab = ProportiesTab.ProportiesTab(self.tabControl, self.proportiesFrame) + self.tabControl.add(self.proportiesFrame, text='Proporties') + self.tabControl.pack(expand=1, fill="both") + + + self.urlFrame = ttk.Frame(self.tabControl) + self.urlTab = URLreportTab.URLreportTab(self.root, self.urlFrame, self.clients[0]) + self.tabControl.add(self.urlFrame,text = 'URL tab') + self.tabControl.pack(expand=1, fill="both") # Pack to make visible + + + self.ipFrame = ttk.Frame(self.tabControl) + self.ipTab = IPreportTab.IPreportTab(self.root, self.ipFrame, self.clients) + self.tabControl.add(self.ipFrame, text='IP tab') + self.tabControl.pack(expand=1, fill="both") + + + self.fileFrame = ttk.Frame(self.tabControl) + self.fileTab = FileReportTab.FileReportTab(self.tabControl, self.fileFrame, self.clients[0]) + self.tabControl.add(self.fileFrame, text='File tab') + self.tabControl.pack(expand=1, fill="both") + + + self.genFrame = ttk.Frame(self.tabControl) + self.genTab = PasswordGeneraorTab.PasswordGeneratorTab(self.tabControl, self.genFrame, ) + self.tabControl.add(self.genFrame, text='generate passowrd') + self.tabControl.pack(expand=1, fill="both") + + + def start(self): + self.root.mainloop() diff --git a/UI/__init__.py b/UI/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/VTPackage/VTApp.py b/VTPackage/VTApp.py deleted file mode 100644 index 4c09985..0000000 --- a/VTPackage/VTApp.py +++ /dev/null @@ -1,35 +0,0 @@ -import tkinter as tk -from tkinter import Menu -from tkinter import ttk -from VTPackage import URLreportTab -from VTPackage import VTClient - - - -class VTApp: - def __init__(self): - self.vtClient = VTClient.VTClient('95d362bc20946172c059611c765f7620da76f98ab4a202565b66cc4bafea9ed9') - self.root = tk.Tk() - self.root.title("VT App") - self.menuBar = Menu() - self.root.config(menu=self.menuBar) - self.fileMenu = Menu(self.menuBar, tearoff=0) - self.fileMenu.add_command(label="New") - self.fileMenu.add_separator() - self.menuBar.add_cascade(label="File", menu=self.fileMenu) - - def _quit(): - self.root.quit() # win will exist when this function is called - self.root.destroy() - exit() - - self.fileMenu.add_command(label="Exit", command=_quit) # command callback - self.tabControl = ttk.Notebook(self.root) # Create Tab Control - self.urlFrame = ttk.Frame(self.tabControl) - self.urlTab = URLreportTab.URLreportTab(self.root,self.urlFrame, self.vtClient) - self.tabControl.add(self.urlFrame,text = 'URL tab') - self.tabControl.pack(expand=1, fill="both") # Pack to make visible - - def start(self): - self.root.mainloop() - diff --git a/VTPackage/VTClient.py b/VTPackage/VTClient.py deleted file mode 100644 index abaddb5..0000000 --- a/VTPackage/VTClient.py +++ /dev/null @@ -1,22 +0,0 @@ -import requests - - -class VTClient: - def __init__(self,apiKey): - self.apiKey=apiKey - - def get_url_report(self,URL): - try: - requestURL = f'https://www.virustotal.com/vtapi/v2/url/report?apikey={self.apiKey}&resource={URL}/' - payload = {} - headers = {} - response = requests.request("GET", requestURL, headers=headers, data=payload) - if response.status_code == 204: - raise Exception("To much API requests") - info = response.json() - if info["response_code"] == 0: - raise Exception(info["verbose_msg"]) - return info - except Exception as e: - print(e) - raise Exception(e) diff --git a/conig.ini b/conig.ini new file mode 100644 index 0000000..4a6e8e4 --- /dev/null +++ b/conig.ini @@ -0,0 +1,6 @@ +[VirusTotal] +apikey = 1a63fb6a442c16a6bebc2966ff2ff7f762d8e8cca1b6371347ddeb0e2fd21347 + +[Shodan] +apikey = 76af1f0KyPrFYGxmdnyHswgSoRHtZJT + diff --git a/transparent.ico b/transparent.ico new file mode 100644 index 0000000000000000000000000000000000000000..4281fa5f096031140162599ecb07190e3e9a5f72 GIT binary patch literal 1406 zcmZQzU<5(|0R|w+!H~hqz#zuJz@P!dKp_SNAO?wpfCEqt4j6$f5FQ1iAut*OqaiRt JL*PG!0033-K^Fi3 literal 0 HcmV?d00001