diff --git a/Final_Merged.py b/Final_Merged.py new file mode 100644 index 0000000..3b05f67 --- /dev/null +++ b/Final_Merged.py @@ -0,0 +1,1996 @@ + +import os +import time +import logging +import subprocess +import tkinter as tk +from tkinter import filedialog, messagebox, ttk +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +import threading +import pandas as pd +import pickle +import numpy as np +from sklearn.preprocessing import MinMaxScaler +import sys +import codecs +import pickle +import csv +import pickle +import psutil +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from tkinter import simpledialog +import pyshark +import psutil +import joblib +from sklearn.preprocessing import StandardScaler +import sklearn.ensemble._forest +from threading import Thread, Event + + + + + + + + + +# Global variable for thread control +stop_event = Event() +value = False + +# Important features and weights as provided +important_features = [ + 'pktcount', + 'byteperflow', + 'tot_kbps', + 'rx_kbps', + 'flows', + 'bytecount', + 'tot_dur', + 'Protocol_ICMP', + 'Protocol_TCP', + 'Protocol_UDP', +] + +# Drop features you don't need based on what you used in training +# Drop features you don't need based on what you used in training +drop_features = ['src', 'dst', 'dt', 'dur', 'pktrate', 'pktperflow', + + 'Protocol_HTTP', + 'Protocol_HTTPS', + 'Protocol_SSH', + 'Protocol_DHCP', + 'Protocol_FTP', + 'Protocol_SMTP', + 'Protocol_POP3', + 'Protocol_IMAP', + 'Protocol_DNS'] + +# Automatically detect active network interface +def get_active_interface(): + interfaces = psutil.net_if_addrs() + for interface, addrs in interfaces.items(): + for addr in addrs: + if addr.family == 2: # AF_INET (IPv4) + if addr.address != '127.0.0.1': # Skip localhost (lo) + return interface + raise Exception("No active interface found") + +# Preprocessing function to extract specific features from packets +def preprocess_packet(packet): + try: + if float(packet.frame_info.time_delta) < 1: + byteperflow = float(packet.length) + else: + byteperflow = float(packet.length) / float(packet.frame_info.time_delta) + + # Capture IP or IPv6 addresses + src_ip = None + dst_ip = None + if hasattr(packet, 'ip'): + src_ip = packet.ip.src + dst_ip = packet.ip.dst + elif hasattr(packet, 'ipv6'): + src_ip = packet.ipv6.src + dst_ip = packet.ipv6.dst + if src_ip and ':' in src_ip: + return None + + # Capture protocol layer + protocol = packet.highest_layer + + # Add flags for common protocols + protocol_icmp = 1 if protocol == "ICMP" else 0 + protocol_tcp = 1 if protocol == "TCP" else 0 + protocol_udp = 1 if protocol == "UDP" else 0 + + features = { + 'pktcount': int(packet.length), + 'byteperflow': byteperflow, + 'tot_kbps': float(packet.length) / 1000.0, + 'rx_kbps': float(packet.length) / 1000.0, + 'flows': 1, + 'bytecount': float(packet.length), + 'tot_dur': float(packet.frame_info.time_delta), + 'Protocol_ICMP': protocol_icmp, + 'Protocol_TCP': protocol_tcp, + 'Protocol_UDP': protocol_udp, + 'src_ip': src_ip, + 'dst_ip': dst_ip, + 'probability': 0.0 + } + + return pd.DataFrame([features]) + except AttributeError: + return None + +def prepare_X_test(packets_list, drop_features): + return None + +def send_prediction(file_path): + url = "http://127.0.0.1:8000/ddos-predictions/" + with open(file_path, 'rb') as f: + files = {'file': f} + response = requests.post(url, files=files) + if response.status_code == 200: + print(f"Successfully sent {file_path} to API.") + else: + print(f"Failed to send {file_path} to API. Status code: {response.status_code}") + +def make_predictions(X_test, X): + logistic_regression_model = joblib.load('logistic_regression_model.pkl') + svm_model = joblib.load('svm_model.pkl') + knn_model = joblib.load('knn_model.pkl') + decision_tree_model = joblib.load('decision_tree_model.pkl') + random_forest_model = joblib.load('random_forest_model.pkl') + + scaler = StandardScaler() + X_test_scaled = scaler.fit_transform(X_test) + + models = { + 'Logistic Regression': logistic_regression_model, + 'SVM': svm_model, + 'KNN': knn_model, + 'Decision Tree': decision_tree_model, + 'Random Forest': random_forest_model + } + + all_predictions = [] + for model_name, model in models.items(): + y_pred = model.predict(X_test_scaled) + all_predictions.append(y_pred) + + transposed_predictions = list(zip(*all_predictions)) + i = 0 + for row in transposed_predictions: + row_sum = sum(row) + avg = row_sum / 5 + X.loc[i, 'probability'] = avg + i += 1 + + with open('predictions.csv', mode='w', newline='') as file: + writer = csv.DictWriter(file, fieldnames=X.keys()) + writer.writeheader() + for index, row in X.iterrows(): + writer.writerow(row.to_dict()) + try: + send_prediction("predictions.csv") + except: + print("could not connect to server") + +def capture_packets(interface=None): + + try: + subprocess.check_call(['sudo', 'apt', 'install', '-y', 'tshark']) + print("tshark installed successfully.") + except subprocess.CalledProcessError: + print("Failed to install tshark. Please install it manually.") + if interface is None: + interface = get_active_interface() + + capture = pyshark.LiveCapture(interface=interface, tshark_path='/usr/bin/tshark') + + + + try: + # print("here") + # capture.sniff(timeout=60) + while value: + # print(value) + packets_list = [] + if stop_event.is_set(): + break + # print("c") + count = 0 + # print(packets_list) + for packet in capture: + # print("Packet", packet) + + # if(count == 15): + # break + # print(f"Packet No. - {count} Received!") + try: + processed_packet = preprocess_packet(packet) + + if processed_packet is not None: + # print(processed_packet["dst_ip"]) + # print(processed_packet["src_ip"]) + + if ":" in processed_packet["dst_ip"] or ":" in processed_packet["src_ip"]: + print("packet isn't correct") + continue + # print(processed_packet) + packets_list.append(processed_packet) + count+=1 + print(count, len(packets_list)) + + # X_test_scaled = prepare_X_test(packets_list, drop_features) + if len(packets_list) >= 1: + X_test = pd.concat(packets_list, ignore_index=True) + X_test_scaled = X_test.drop(drop_features, axis=1, errors='ignore') + X_test_scaled = X_test_scaled.reindex(columns=important_features, fill_value=0) + + if X_test_scaled is not None: + make_predictions(X_test_scaled,X_test) + time.sleep(10) + + except AttributeError as e: + print(f"Error processing packet: {e}") + print("Packets being Captured..!") + + + except KeyboardInterrupt: + print("\nPacket capturing stopped.") + +def start_capture(): + global thread + if os.geteuid() != 0: + root.withdraw() # Hide the main window + password = simpledialog.askstring("Password", "Enter your sudo password and run again:", show='*') + if password: + try: + subprocess.run(['sudo', '-S', sys.executable] + sys.argv, input=password.encode(), check=True) + except subprocess.CalledProcessError: + messagebox.showerror("Error", "Failed to run the script with sudo.") + finally: + root.destroy() + else: + messagebox.showerror("Error", "No password provided. Unable to run with sudo.") + elif not stop_event.is_set(): + global value + value = True + stop_event.clear() + thread = Thread(target=capture_packets) + thread.start() + + start_button.config(state=tk.DISABLED) + stop_button.config(state=tk.NORMAL) + + + + +def stop_capture(): + global value + value = False + stop_event.set() + if thread.is_alive(): + thread.join() + start_button.config(state=tk.NORMAL) + stop_button.config(state=tk.DISABLED) + root.destroy() + +def setup_gui(frame): + global start_button, stop_button, thread + start_button = tk.Button(frame, text="Start Capture", command=start_capture) + start_button.pack(pady=20) + + stop_button = tk.Button(frame, text="Stop Capture", command=stop_capture, state=tk.DISABLED) + stop_button.pack(pady=20) + + + + + + + +#rensoomware tested +import os +import subprocess +import sys +import csv +import pickle +import pandas as pd +import tkinter as tk +from tkinter import filedialog +from tkinter import messagebox +import requests +import psutil +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler + +value = True + +# Function to get CPU and memory usage percentages +def get_usage_percentages(): + cpu_usage = psutil.cpu_percent(interval=1) + memory_percent = psutil.virtual_memory().percent + return cpu_usage, memory_percent + +# Function to send usage data to the API +def send_data_to_api(cpu_usage, memory_usage): + api_url = 'http://127.0.0.1:8000/usage_log/' # Update this if needed + payload = { + 'cpu_usage': cpu_usage, + 'memory_usage': memory_usage + } + try: + response = requests.post(api_url, json=payload) + if response.status_code == 201: + print("Data logged successfully.") + else: + print("Failed to log data:", response.json()) + except Exception as e: + print("Error while sending data:", str(e)) + +# Function to send ransomware prediction data to the API +def send_predictions_to_api(file_path): + url = "http://127.0.0.1:8000/ransomware-type-predictions/" + with open(file_path, 'rb') as f: + files = {'file': f} + response = requests.post(url, files=files) + if response.status_code == 200: + print(f"Successfully sent {file_path} to API.") + else: + print(f"Failed to send {file_path} to API. Status code: {response.status_code}") + +# Function to browse directory using Tkinter +def browse_directory(): + """Open a dialog to choose a directory.""" + root = tk.Tk() + root.withdraw() # Hide the root window + directory = filedialog.askdirectory(title="Select a Directory") + return directory + +# Function to calculate the MD5 hash of a file +def md5_hash(file_path): + result = subprocess.run(['md5sum', file_path], capture_output=True, text=True) + return result.stdout.split()[0] + +# Extract machine type from ELF file +def get_machine_type(file_path): + try: + result = subprocess.run(['readelf', '-h', file_path], capture_output=True, text=True) + for line in result.stdout.splitlines(): + if 'Machine:' in line: + return line.split(':')[1].strip() + except Exception as e: + print(f"Error getting machine type: {e}") + return None + +# Extract number of sections from ELF file +def get_number_of_sections(file_path): + try: + result = subprocess.run(['readelf', '-h', file_path], capture_output=True, text=True) + for line in result.stdout.splitlines(): + if 'Number of section headers:' in line: + return int(line.split(':')[1].strip()) + except Exception as e: + print(f"Error getting number of sections: {e}") + return None + +# Extract resource size from ELF file +def get_resource_size(file_path): + try: + result = subprocess.run(['readelf', '-S', file_path], capture_output=True, text=True) + for line in result.stdout.splitlines(): + if '.rodata' in line: + size_hex = line.split()[5] + return int(size_hex, 16) + except Exception as e: + print(f"Error getting resource size: {e}") + return 0 + +# Extract linker version from ELF file +def get_linker_version(file_path): + try: + result = subprocess.run(['objdump', '-p', file_path], capture_output=True, text=True) + for line in result.stdout.splitlines(): + if 'Version:' in line: + version = line.split(':')[1].strip() + major_version = version.split('.')[0] + minor_version = version.split('.')[1] if '.' in version else '0' + return major_version, minor_version + except Exception as e: + print(f"Error getting linker version: {e}") + return None, None + +# Extract dynamic linking information from ELF file +def get_dynamic_info(file_path): + try: + result = subprocess.run(['readelf', '-d', file_path], capture_output=True, text=True) + dynamic_info = [] + for line in result.stdout.splitlines(): + dynamic_info.append(line) + return dynamic_info + except Exception as e: + print(f"Error getting dynamic linking info: {e}") + return None + +# Function to extract features from an ELF file +def extract_features(file_path): + features = { + 'FileName': file_path, + 'md5Hash': md5_hash(file_path), + 'Machine': get_machine_type(file_path), + 'NumberOfSections': get_number_of_sections(file_path), + 'ResourceSize': get_resource_size(file_path), + 'LinkerVersionMajor': None, + 'LinkerVersionMinor': None, + 'DynamicInfo': get_dynamic_info(file_path) + } + + # Get linker version + major_version, minor_version = get_linker_version(file_path) + features['LinkerVersionMajor'] = major_version + features['LinkerVersionMinor'] = minor_version + + return features + +# Function to find ELF files in the selected directory +def find_elf_file(start_dir, status_label): + if not os.path.isdir(start_dir): + return + + try: + find_command = [ + 'find', start_dir, + '(', '-path', '/proc', '-o', '-path', '/sys', '-o', '-path', '/run', ')', '-prune', '-o', + '-type', 'f', '-print' + ] + find_result = subprocess.run(find_command, capture_output=True, text=True, check=False) + + if find_result.returncode != 0: + print(f"Error running find command: {find_result.stderr}", file=sys.stderr) + return + + file_paths = find_result.stdout.splitlines() + print(f"Found files in {start_dir}:") + print(file_paths) + + for file_path in file_paths: + try: + file_command = ['file', '--mime-type', file_path] + file_result = subprocess.run(file_command, capture_output=True, text=True, check=True) + + if 'application/x-executable' in file_result.stdout or 'application/x-sharedlib' in file_result.stdout: + status_label.config(text=f"Processing: {os.path.basename(file_path)}") + status_label.update() + + if os.path.exists(file_path): + try: + extracted_features = extract_features(file_path) + except: + print("Error Reading File" + file_path) + continue + + with open('data.csv', 'a', newline='') as file: + writer = csv.writer(file) + writer.writerow(extracted_features.values()) + + else: + print("File not found!") + except subprocess.CalledProcessError as e: + print(f"Error running file command on {file_path}: {e}", file=sys.stderr) + + except Exception as e: + print(f"Error processing directory {start_dir}: {e}", file=sys.stderr) + +# Function to load the model +def load_model(): + with open('model.pkl', 'rb') as f: + model = pickle.load(f) + return model + +# Function to predict ransomware based on features +def predictransomware(file_path): + model = load_model() + + # Extract features from the given file + features = extract_features(file_path) + feature_df = pd.DataFrame([features]) + + # Predict ransomware type + prediction = model.predict(feature_df.drop(columns=['FileName', 'md5Hash', 'Machine', 'DynamicInfo'])) + return prediction[0] + +# Function to run predictions on selected ELF files +def run_predictions(selected_dir, status_label): + csv_filename = "data.csv" + with open(csv_filename, mode='w', newline='') as file: + writer = csv.writer(file) + writer.writerow(['FileName', + 'md5Hash', + 'Machine', + 'NumberOfSections', + 'ResourceSize', + 'LinkerVersionMajor', + 'LinkerVersionMinor', + 'DynamicInfo']) # Write header if file is new + + csv_filename = "predictions.csv" + with open(csv_filename, mode='w', newline='') as file: + writer = csv.writer(file) + writer.writerow(['filename', 'predicted_class']) # Write header if file is new + + if selected_dir: + status_label.config(text="Processing...") + status_label.update() + find_elf_file(selected_dir, status_label) + + with open("data.csv", "r") as file: + reader = csv.DictReader(file) + files = [row['FileName'] for row in reader] + for ransomware_file in files: + print(ransomware_file) + result = predictransomware(ransomware_file) + + csv_filename = "predictions.csv" + file_exists = os.path.exists(csv_filename) + + with open(csv_filename, mode='a', newline='') as file: + writer = csv.writer(file) + if not file_exists: + writer.writerow(['filename', 'predicted_class']) + writer.writerow([os.path.basename(ransomware_file), result]) + + status_label.config(text="Predictions Saved") + + try: + send_predictions_to_api("predictions.csv") + except: + print("Connection to API failed") + + try: + cpu_percent, memory_percent = get_usage_percentages() + send_data_to_api(cpu_percent, memory_percent) + except: + print("Connection to API failed") + else: + status_label.config(text="No directory selected") + global value + if(value): + value = False + print("VALLLLLL") + start_watchdog(selected_dir, status_label) + + +# Watchdog Event Handler +class WatcherHandler(FileSystemEventHandler): + def __init__(self, status_label): + self.status_label = status_label + + def on_modified(self, event): + if event.is_directory: + return + else: + print(f"File modified: {event.src_path}") + run_predictions(os.path.dirname(event.src_path), self.status_label) + + def on_created(self, event): + if event.is_directory: + return + else: + print(f"File created: {event.src_path}") + run_predictions(os.path.dirname(event.src_path), self.status_label) + +# Function to start the watchdog observer +def start_watchdog(directory, status_label): + event_handler = WatcherHandler(status_label) + observer = Observer() + observer.schedule(event_handler, path=directory, recursive=True) + observer.start() + print(f"Started monitoring {directory} for changes.") + return observer +# Entry point to run predictions for selected directory +if __name__ == "__main__": + selected_directory = sys.argv[1] if len(sys.argv) > 1 else None + if selected_directory: + run_predictions(selected_directory) + else: + print("Please specify a directory.") + + + + +#remsomwareaudit +import tkinter as tk +from tkinter import messagebox +import subprocess +import os +import csv +import inotify_simple +import threading +import time +import re +import requests +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from collections import defaultdict +import numpy as np +import pandas as pd +from sklearn.preprocessing import StandardScaler +import tensorflow as tf +from sklearn.metrics import accuracy_score, confusion_matrix, classification_report +from datetime import datetime + +permission_operations = None +# Define event masks manually +IN_CREATE = 0x00000100 +IN_DELETE = 0x00000200 +IN_MODIFY = 0x00000002 +IN_OPEN = 0x00000020 +IN_ISDIR = 0x40000000 + +#################### + + +TEST_DATA_PATH = 'combined_log_summary.csv' +VARIABLE_NAMES_PATH = 'output.txt' +def predict_ransomware(): +# Load the trained model + model = tf.keras.models.load_model('updated_ransomware_classifier.h5') + + # Load and prepare test data + # Read variable names + with open(VARIABLE_NAMES_PATH, encoding='utf-8') as f: + columns = [line.split(';')[1].strip() for line in f] + + # Load test data + data = pd.read_csv(TEST_DATA_PATH, header=None, names=columns) + + # Check and clean column names + data.columns = data.columns.str.strip() + X = data + # Standardize the features + scaler = StandardScaler() + X = scaler.fit_transform(X) + + # Make predictions + predictions = model.predict(X) + predicted_labels = (predictions > 0.5).astype(int) + + + # Convert predictions to "Yes" or "No" + predicted_labels_text = ['Yes' if label == 1 else 'No' for label in predicted_labels.flatten()] + + + # Get current timestamp + timestamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + + + # Save predictions and true labels to a CSV file with timestamp + output_df = pd.DataFrame({ + 'Timestamp': [timestamp] * len(predicted_labels_text), # Add timestamp column + 'Predicted Label': predicted_labels_text + }) + + output_file = f'prediction.csv' + output_df.to_csv(output_file, index=False) + print(f"Predictions saved to {output_file} ({timestamp})") + + + def send_predictions_to_api(file_path): + url = "http://127.0.0.1:8000/predict-malware/" + with open(file_path, 'rb') as f: + files = {'file': f} + response = requests.post(url, files=files) + if response.status_code == 200: + print(f"Successfully sent {file_path} to API.") + else: + print(f"Failed to send {file_path} to API. Status code: {response.status_code}") + try: + send_predictions_to_api(output_file) + except: + print("Error Connection Server") + +#################### + +ID = 0 + +is_flip = 0 +flipped = False +class PermissionChangeHandler(FileSystemEventHandler): + def __init__(self): + super().__init__() + self.file_types = set() + + def get_file_extension(self, file_path): + """Extracts the file extension from the file path.""" + _, ext = os.path.splitext(file_path) + return ext.strip(".") # Strip the dot from the extension + + def on_modified(self, event): + if not event.is_directory: + file_path = event.src_path + file_extension = self.get_file_extension(file_path) + + # Collect all file types + file_types = set() + for operations in permission_operations.values(): + for key in operations: + match = re.search(r'\.\w+$', key) + if match: + file_types.add(match.group().strip('.')) + + if file_extension in file_types: + current_permissions = oct(os.stat(file_path).st_mode & 0o777) + + + # Check all operations (chmod/chown) for this file type + for operation, perms in permission_operations.items(): + for key in perms: + if file_extension in key: + perms[key] += 1 + # print(f"Updated {operation} for {file_extension}: {perms[key]}") + +class AuditDManagerApp: + def __init__(self, frame): + self.frame = frame + # self.root = frame + # self.root.title("AuditD Manager") + # self.root.geometry("400x350") + # # Adjusted for additional widget + self.frame.pack(fill='both', expand=True) + + + # Create Widgets + self.install_button = tk.Button(self.frame , text="Install AuditD", command=self.install_auditd) + self.install_button.pack(pady=10) + + self.start_button = tk.Button(self.frame , text="Start AuditD", command=self.start_auditd) + self.start_button.pack(pady=10) + + self.stop_button = tk.Button(self.frame , text="Stop AuditD", command=self.stop_auditd) + self.stop_button.pack(pady=10) + + self.status_button = tk.Button(self.frame, text="Check Status", command=self.check_status) + self.status_button.pack(pady=10) + + + # Add Text Entry for Watch Path + + # Initialize monitoring flags and data structures + self.monitoring = False + self.log_file = "/var/log/audit/audit.log" + self.combined_csv_file = "combined_log_summary.csv" + self.monitored_files_set = { + 'bash.bashrc', 'bash_completion.d', 'environment', 'fstab', 'fwupd', 'group', 'host.conf', 'hosts', 'init.d', + 'inputrc', 'ld.so.cache', 'locale.alias', 'locale.conf', 'login.defs', 'machine-id', 'modprobe.d', 'nsswitch.conf', + 'passwd', 'sensors.d', 'sensors3.conf', 'shadow', 'shells', 'sudo.conf', 'sudoers', 'sudoers.d' + } + self.log_counts = {key: 0 for key in [ + 'Id','PROCTITLE', 'AVC', 'SYSCALL', 'USER_AUTH', 'USER_ACCT', + 'USER_CMD', 'CRED_REFR', 'USER_START', 'USER_AVC', 'USER_END', 'CRED_DISP', 'CRED_ACQ', + 'LOGIN', 'SERVICE_START', 'SERVICE_STOP']} + + # Track file extensions + self.ext_count = {ext: {'modified': 0, 'created': 0, 'deleted': 0, 'opened': 0} for ext in [ + '.db', '.AR', '.01', '.GIF', '.TXT', '.scc', '.dat', '.bmp', '.STF', '.scf', + '.exe', '.typelib', '.cl', '.ocx', '.xml', '.json', '.csv', '.html', '.css', + '.js', '.py', '.log', '.sql', '.pdf', '.doc', '.docx', '.ppt', '.pptx', + '.xlsx', '.jpg', '.jpeg', '.png', '.mp4', '.mp3', '.zip', '.tar', '.gz', '.rar', '.7z', '.apk', '.iso']} + + # Track permission operations + global permission_operations + permission_operations = { + 'chmod': {f'chmod{perm}{ext}': 0 for perm in ['644', '755', '777'] for ext in self.ext_count}, + 'chown': {f'chown{owner}{ext}': 0 for owner in ['user', 'group'] for ext in self.ext_count}, + 'chgrp': {f'chgrp{group}{ext}': 0 for group in ['staff', 'admin'] for ext in self.ext_count} + } + + # Directory operations tracking + self.directory_count = {'created': 0, 'deleted': 0, 'modified': 0, 'opened': 0} + + # Initialize inotify + self.inotify = inotify_simple.INotify() + self.EVENT_MASKS = IN_CREATE | IN_DELETE | IN_MODIFY | IN_OPEN | IN_ISDIR + self.watch_path = '/etc' # Default path, will be updated + self.watch_descriptor2 = self.inotify.add_watch(self.watch_path, self.EVENT_MASKS) + + # Observer for filesystem events + self.observer = None + self.event_handler = None + self.monitor_thread = threading.Thread(target=self.monitor_logs) + + # Initialize file monitoring data + self.open_count = defaultdict(int) + + def run_command(self, command, success_message, error_message): + try: + result = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + messagebox.showinfo("Success", success_message) + except subprocess.CalledProcessError as e: + messagebox.showerror("Error", f"{error_message}\n\n{e.stderr.decode()}") + + def prompt_for_password(self, command, success_message, error_message): + password_window = tk.Toplevel(self) + password_window.title("Enter Sudo Password") + + tk.Label(password_window, text="Enter your sudo password:").pack(pady=10) + + password_entry = tk.Entry(password_window, show="*") + password_entry.pack(pady=5) + + def on_submit(): + password = password_entry.get() + password_window.destroy() + if not password: + messagebox.showwarning("Input Error", "Please enter your sudo password.") + return + + full_command = f"echo {password} | sudo -S {command}" + self.run_command(full_command, success_message, error_message) + tk.Button(password_window, text="Submit", command=on_submit).pack(pady=10) + + def install_auditd(self): + command = "sudo apt-get update && sudo apt-get install -y auditd" + self.prompt_for_password(command, "AuditD installed successfully!", "Failed to install AuditD.") + + def start_auditd(self): + command = "sudo systemctl start auditd" + self.prompt_for_password(command, "AuditD started successfully!", "Failed to start AuditD.") + self.start_monitoring() + + def stop_auditd(self): + command = "sudo systemctl stop auditd" + self.prompt_for_password(command, "AuditD stopped successfully!", "Failed to stop AuditD.") + self.stop_monitoring() + + def check_status(self): + command = "systemctl status auditd" + try: + result = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + status = result.stdout.decode() + messagebox.showinfo("AuditD Status", status) + except subprocess.CalledProcessError as e: + messagebox.showerror("Error", f"Failed to check status of AuditD.\n\n{e.stderr.decode()}") + + def start_monitoring(self): + self.monitoring = True + if not self.monitor_thread.is_alive(): + self.monitor_thread = threading.Thread(target=self.monitor_logs) + self.monitor_thread.start() + + # Get the user-defined watch path + self.watch_path = '/etc' # Default to root if empty + self.watch_descriptor = self.inotify.add_watch(self.watch_path, self.EVENT_MASKS) + + # Start filesystem event monitoring + if self.observer is None: + self.event_handler = PermissionChangeHandler() + self.observer = Observer() + self.observer.schedule(self.event_handler, '/home', recursive=True) + self.observer.start() + + def stop_monitoring(self): + self.monitoring = False + if self.monitor_thread.is_alive(): + self.monitor_thread.join() + + # Stop filesystem event monitoring + if self.observer: + self.observer.stop() + self.observer.join() + + def monitor_logs(self): + while self.monitoring: + if os.path.exists(self.log_file): + with open(self.log_file, 'r') as f: + lines = f.readlines() + + for line in lines: + if 'type=' in line: + log_type = line.split('type=')[1].split(' ')[0] + if log_type in self.log_counts: + self.log_counts[log_type] += 1 + + self.update_csv() + + self.monitor_extensions() + predict_ransomware() + time.sleep(5) # Sleep for one second before the next update + + def update_csv(self): + # headers = [ + # 'Id' ,'PROCTITLE', 'AVC', 'SYSCALL', 'USER_AUTH', 'USER_ACCT', + # 'USER_CMD', 'CRED_REFR', 'USER_START', 'USER_AVC', 'USER_END', 'CRED_DISP', 'CRED_ACQ', + # 'LOGIN', 'SERVICE_START', 'SERVICE_STOP' + # ] + [f'chmod{perm}{ext}' for perm in ['644', '755', '777'] for ext in self.ext_count] + \ + # [f'chown{owner}{ext}' for owner in ['user', 'group'] for ext in self.ext_count] + \ + # [f'chgrp{group}{ext}' for group in ['staff', 'admin'] for ext in self.ext_count] + \ + # [f'Modified({ext})' for ext in self.ext_count] + \ + # [f'Created({ext})' for ext in self.ext_count] + \ + # [f'Deleted({ext})' for ext in self.ext_count] + \ + # [f'Opened({ext})' for ext in self.ext_count] + \ + # ['Directories Created', 'Directories Deleted', 'Directories Modified', 'Directories Opened']+ \ + # list(self.monitored_files_set) + + global ID + ID += 1 + global is_flip + global flipped + if flipped: + is_flip = 1 + flipped = False + else: + is_flip = 0 + flipped = True + + row = [ + ID, + self.log_counts.get('PROCTITLE', 0), + self.log_counts.get('AVC', 0), + self.log_counts.get('SYSCALL', 0), + self.log_counts.get('USER_AUTH', 0), + self.log_counts.get('USER_ACCT', 0), + self.log_counts.get('USER_CMD', 0), + self.log_counts.get('CRED_REFR', 0), + self.log_counts.get('USER_START', 0), + self.log_counts.get('USER_AVC', 0), + self.log_counts.get('USER_END', 0), + self.log_counts.get('CRED_DISP', 0), + self.log_counts.get('CRED_ACQ', 0), + self.log_counts.get('LOGIN', 0), + self.log_counts.get('SERVICE_START', 0), + self.log_counts.get('SERVICE_STOP', 0), + ] + + # print(permission_operations['chmod']) + # Add permission operations and extensions + row.extend(permission_operations['chmod'].values()) + row.extend(permission_operations['chown'].values()) + row.extend(permission_operations['chgrp'].values()) + + # Add extension counts for modification, creation, deletion, and opening + for ext in self.ext_count: + row.extend([ + self.ext_count[ext]['modified'], + self.ext_count[ext]['created'], + self.ext_count[ext]['deleted'], + self.ext_count[ext]['opened'], + ]) + + # Add directory counts + row.extend([ + self.directory_count['created'], + self.directory_count['deleted'], + self.directory_count['modified'], + self.directory_count['opened'] + ]) + + # Add monitored files open counts + row.extend(self.open_count.get(file, 0) for file in sorted(self.monitored_files_set)) + + # Write to CSV, append if file exists + file_exists = os.path.isfile(self.combined_csv_file) + with open(self.combined_csv_file, 'a', newline='') as csv_file: + writer = csv.writer(csv_file) + if not file_exists: + pass + writer.writerow(row) + + + def monitor_extensions(self): + events = self.inotify.read(timeout=100000) + for event in events: + (_, event_types, _, filename) = event + + filename = event.name + ext = os.path.splitext(filename)[1] + if ext in self.ext_count: + if event.mask & IN_CREATE: + self.ext_count[ext]['created'] += 1 + if event.mask & IN_DELETE: + self.ext_count[ext]['deleted'] += 1 + if event.mask & IN_MODIFY: + self.ext_count[ext]['modified'] += 1 + if event.mask & IN_OPEN: + self.ext_count[ext]['opened'] += 1 + if filename in self.monitored_files_set: + self.open_count[filename] += 1 + + if event.mask & IN_ISDIR: + if event.mask & IN_CREATE: + self.directory_count['created'] += 1 + if event.mask & IN_DELETE: + self.directory_count['deleted'] += 1 + if event.mask & IN_MODIFY: + self.directory_count['modified'] += 1 + if event.mask & IN_OPEN: + self.directory_count['opened'] += 1 + + + + + + + + + + + + + + + + + +#malwaretested + + + + + + + + + + + + +import os +import time +import logging +import subprocess +import tkinter as tk +from tkinter import filedialog, messagebox, ttk +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +import threading +import pandas as pd +import pickle +import numpy as np +from sklearn.preprocessing import MinMaxScaler +import sys +import os +import pandas as pd +import numpy as np +import codecs +import pickle +import requests + + + +isMonitoring = False + +output_directory = "outputs" +bytes_output_directory = "outputs/bytes_output" +asm_output_directory = "outputs/asm_output" +result_folder = "results" +bytes_result_directory = "results/bytes_result" +asm_result_directory = "results/asm_result" +bytes_model_directory = "bytes_models" +asm_model_directory = "asm_models" + +if not os.path.exists(asm_model_directory) or not os.path.exists(bytes_model_directory): + messagebox.showinfo("Error", "Models Not Found for Prediction") + exit(-1) + +if not os.path.exists(output_directory): + os.makedirs(output_directory) + +if not os.path.exists(asm_output_directory): + os.makedirs(asm_output_directory) + +if not os.path.exists(bytes_output_directory): + os.makedirs(bytes_output_directory) + +if not os.path.exists(result_folder): + os.makedirs(result_folder) + +if not os.path.exists(asm_result_directory): + os.makedirs(asm_result_directory) + +if not os.path.exists(bytes_result_directory): + os.makedirs(bytes_result_directory) + +logging.basicConfig(level=logging.INFO) + + + + +def send_predictions_to_api(file_path): + url = "http://127.0.0.1:8000/predict-malware/" + with open(file_path, 'rb') as f: + files = {'file': f} + response = requests.post(url, files=files) + if response.status_code == 200: + print(f"Successfully sent {file_path} to API.") + else: + print(f"Failed to send {file_path} to API. Status code: {response.status_code}") + + +def send_asm_predictions_to_api(file_path): + url = "http://127.0.0.1:8000/predict-malware/" + with open(file_path, 'rb') as f: + files = {'file': f} + response = requests.post(url, files=files) + if response.status_code == 200: + print(f"Successfully sent {file_path} to API.") + else: + print(f"Failed to send {file_path} to API. Status code: {response.status_code}") + + + +def format_bytes_to_hex(data): + hex_dump = "" + for i in range(0, len(data), 16): + chunk = data[i:i+16] + hex_values = " ".join(f"{byte:02X}" for byte in chunk) + address = f"{i:08X}" + hex_dump += f"{address} {hex_values}\n" + return hex_dump + +def convert_file_to_hex(input_file, output_file): + try: + with open(input_file, 'rb') as f: + data = f.read() + + hex_dump = format_bytes_to_hex(data) + + with open(output_file, 'w') as f: + f.write(hex_dump) + + logging.info(f"Converted '{input_file}' to hex dump and saved to '{output_file}'") + except Exception as e: + logging.error(f"Error converting '{input_file}': {e}") + +def scan_and_convert_directory(directory, output_dir): + for root, _, files in os.walk(directory, followlinks=True): + for filename in files: + input_file = os.path.join(root, filename) + if not filename.endswith(".bytes"): + output_file = os.path.join(output_dir, f"{filename}.bytes") + if not os.path.exists(output_file): + convert_file_to_hex(input_file, output_file) + +class FileChangeHandler(FileSystemEventHandler): + def __init__(self, output_dir, hex_dirs, disasm_dirs): + self.output_dir = output_dir + self.hex_dirs = hex_dirs + self.disasm_dirs = disasm_dirs + super().__init__() + + def on_created(self, event): + if not event.is_directory: + input_file = event.src_path + output_file_hex = os.path.join(bytes_output_directory, f"{os.path.basename(input_file)}.bytes") + if not os.path.exists(output_file_hex): + # Convert to hex in a new thread + threading.Thread(target=self.run_hex_conversion, args=(input_file, output_file_hex)).start() + threading.Thread(target=self.run_disassembly, args=(input_file,)).start() + + # Disassemble in a new thread + + def run_hex_conversion(self, input_file, output_file): + convert_file_to_hex(input_file, output_file) + run_malware_ai_analysis_bytes() + def run_disassembly(self, file_path): + try: + print(f"Disassembling {file_path}") + result = subprocess.run(['objdump', '-d', file_path], capture_output=True, text=True, check=True) + assembly_code = result.stdout + + base_name = os.path.basename(file_path) + if not file_path.endswith(".asm"): + asm_file_name = f"{base_name}.asm" + asm_file_path = os.path.join(asm_output_directory, asm_file_name) + + with open(asm_file_path, "w") as asm_file: + asm_file.write(assembly_code) + + print(f"Disassembly complete. Assembly code saved to {asm_file_path}") + run_malware_analysis_asm() + except subprocess.CalledProcessError as e: + print(f"Error disassembling file {file_path}: {e}", file=sys.stderr) + +def monitor_directories(directories, output_dir): + event_handler = FileChangeHandler(output_dir, hex_dirs=directories, disasm_dirs=directories) + observer = Observer() + for directory in directories: + observer.schedule(event_handler, path=directory, recursive=True) + logging.info(f"Monitoring directory: {directory}") + + observer.start() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + observer.stop() + observer.join() + + +def start_observer(directories, output_dir): + + observer = Observer() + event_handler = FileChangeHandler(output_dir, hex_dirs=directories, disasm_dirs=directories) + for directory in directories: + observer.schedule(event_handler, path=directory, recursive=True) + logging.info(f"Monitoring directory: {directory}") + + observer.start() + return observer + + + +def disassemble_elf(file_path, output_dir): + try: + print(f"Disassembling {file_path}") + result = subprocess.run(['objdump', '-d', file_path], capture_output=True, text=True, check=True) + assembly_code = result.stdout + + base_name = os.path.basename(file_path) + if not file_path.endswith(".asm"): + asm_file_name = f"{base_name}.asm" + asm_file_path = os.path.join(output_dir, asm_file_name) + + with open(asm_file_path, "w") as asm_file: + asm_file.write(assembly_code) + + print(f"Disassembly complete. Assembly code saved to {asm_file_path}") + + except subprocess.CalledProcessError as e: + print(f"Error disassembling file {file_path}: {e}", file=sys.stderr) + +def find_elf_files(start_dirs): + elf_files = [] + for start_dir in start_dirs: + if not os.path.isdir(start_dir): + continue + + try: + find_command = ['find', start_dir, '-path', '/proc', '-prune', '-o', '-path', '/sys', '-prune', '-o', '-path', '/run', '-prune', '-o', '-type', 'f', '-print'] + find_result = subprocess.run(find_command, capture_output=True, text=True, check=False) + + if find_result.returncode != 0: + print(f"Error running find command: {find_result.stderr}", file=sys.stderr) + continue + + file_paths = find_result.stdout.splitlines() + print(f"Found files in {start_dir}:") + print(file_paths) + + for file_path in file_paths: + try: + file_command = ['file', '--mime-type', file_path] + file_result = subprocess.run(file_command, capture_output=True, text=True, check=True) + + if 'application/x-executable' in file_result.stdout or 'application/x-sharedlib' in file_result.stdout: + elf_files.append(file_path) + except subprocess.CalledProcessError as e: + print(f"Error running file command on {file_path}: {e}", file=sys.stderr) + + except Exception as e: + print(f"Error processing directory {start_dir}: {e}", file=sys.stderr) + + print(f"Found ELF files: {elf_files}") + return elf_files + +def process_files(output_dir, start_dirs): + os.makedirs(output_dir, exist_ok=True) + elf_files = find_elf_files(start_dirs) + + if not elf_files: + print("No ELF files found.") + return + + for elf_file in elf_files: + disassemble_elf(elf_file, output_dir) + + print("Disassembly complete. Assembly files are saved in the output directory.") + +def process_files_malware(folder_path, files_to_process): + feature_matrix = np.zeros((len(files_to_process), 258), dtype=int) # Adjusted to 258 columns + + for k, file in enumerate(files_to_process): + if file.endswith("bytes"): + try: + with open(os.path.join(folder_path, file), "r") as byte_file: + for lines in byte_file: + line = lines.rstrip().split(" ") + for hex_code in line: + if hex_code != '??': + index = int(hex_code, 16) + if index < 257: # Keep the bounds check for 257 + feature_matrix[k][index] += 1 + else: + feature_matrix[k][257] += 1 # This now references the 258th feature + except: + continue + # Normalize the features + scaler = MinMaxScaler() + feature_matrix = scaler.fit_transform(feature_matrix) + + return feature_matrix + +def test_files(folder_path, model_path, output_csv): + files = os.listdir(folder_path) + + # Check if the CSV file already exists + if os.path.exists(output_csv): + existing_results = pd.read_csv(output_csv) + already_scanned_files = set(existing_results['File'].tolist()) + else: + already_scanned_files = set() + + # Filter out files that have already been scanned + files_to_process = [file for file in files if file not in already_scanned_files] + + if not files_to_process: + print("All files have already been scanned.") + return + + # Process only the files that haven't been scanned yet + feature_matrix = process_files_malware(folder_path, files_to_process) + + # Load the trained model + with open(model_path, 'rb') as model_file: + model = pickle.load(model_file) + + # Make predictions + predictions = model.predict(feature_matrix) + prediction_probs = model.predict_proba(feature_matrix) + + # Create a DataFrame for the new results + new_results = pd.DataFrame({ + 'File': files_to_process, + 'Predicted Class': predictions, + 'Prediction Probability': [max(probs) for probs in prediction_probs] + }) + + # Append new results to the existing CSV file or create a new one + if os.path.exists(output_csv): + new_results.to_csv(output_csv, mode='a', header=False, index=False) + else: + new_results.to_csv(output_csv, index=False) + + print(f"New predictions appended to {output_csv}") + +def run_malware_ai_analysis_bytes(): + print("bytes malware analysis started") + directory = bytes_output_directory + model_files = bytes_model_directory + + model_folder = model_files # Folder containing the .pkl files + model_files = [f for f in os.listdir(model_folder) if f.endswith('.pkl')] + + for model_file in model_files: + model_path = os.path.join(model_folder, model_file) + output_csv = os.path.join(bytes_result_directory, f"bytes_predictions_{os.path.splitext(model_file)[0]}.csv") + test_files(directory, model_path, output_csv) + try: + send_predictions_to_api(output_csv) + except: + print("Connection Failed") + + + + +def preprocess_asm_file(file_path): + prefixes = ['.text:', '.Pav:', '.idata:', '.data:', '.bss:', '.rdata:', '.edata:', '.rsrc:', '.tls:', '.reloc:', '.BSS:', '.CODE'] + opcodes = ['jmp', 'mov', 'retf', 'push', 'pop', 'xor', 'retn', 'nop', 'sub', 'inc', 'dec', 'add', 'imul', 'xchg', 'or', 'shr', 'cmp', 'call', 'shl', 'ror', 'rol', 'jnb', 'jz', 'rtn', 'lea', 'movzx'] + keywords = ['.dll', 'std::', ':dword'] + registers = ['edx', 'esi', 'eax', 'ebx', 'ecx', 'edi', 'ebp', 'esp', 'eip'] + + # Initialize counts + prefix_counts = np.zeros(len(prefixes), dtype=int) + opcode_counts = np.zeros(len(opcodes), dtype=int) + keyword_counts = np.zeros(len(keywords), dtype=int) + register_counts = np.zeros(len(registers), dtype=int) + + # Process file + with open(file_path, 'r', encoding='cp1252', errors='replace') as f: + for line in f: + line = line.rstrip().split() + if not line: + continue + l = line[0] + for i, prefix in enumerate(prefixes): + if prefix in l: + prefix_counts[i] += 1 + line = line[1:] + for i, opcode in enumerate(opcodes): + if any(opcode == li for li in line): + opcode_counts[i] += 1 + for i, register in enumerate(registers): + if any(register in li and ('text' in l or 'CODE' in l) for li in line): + register_counts[i] += 1 + for i, keyword in enumerate(keywords): + if any(keyword in li for li in line): + keyword_counts[i] += 1 + + # Create feature vector + feature_vector = np.concatenate([prefix_counts, opcode_counts, register_counts, keyword_counts]) + + return feature_vector + + +# Main function to load models and make predictions +def run_malware_analysis_asm(asm_folder_path=asm_output_directory, models_folder=asm_model_directory): + print("Starting analysis...") + + # Get all .asm files in the folder + asm_files = [f for f in os.listdir(asm_folder_path) if f.endswith('.asm')] + + # Load all .pkl models from the models folder + model_files = [f for f in os.listdir(models_folder) if f.endswith('.pkl')] + + models = {} + for model_file in model_files: + model_name = os.path.splitext(model_file)[0] + with open(os.path.join(models_folder, model_file), 'rb') as f: + model_clf = pickle.load(f) + models[model_name] = model_clf + + # Prediction and saving results + for model_name, model_clf in models.items(): + print(f"Making asm predictions with {model_name}...") + + # Generate the correct class mapping + def get_class_mapping(model_name): + if model_name == 'XGBClassifier': + return {i: i for i in range(9)} # XGB uses 0-8 + else: + return {i: i+1 for i in range(9)} # Other models use 1-9 + + class_mapping = get_class_mapping(model_name) + + # Check if result file for the model already exists + results_file_path = f'{asm_result_directory}/asm_prediction_{model_name}.csv' + if os.path.exists(results_file_path): + results_df = pd.read_csv(results_file_path) + else: + results_df = pd.DataFrame(columns=['file_name', 'prediction', 'probability']) + + new_predictions = [] + + for asm_file in asm_files: + if asm_file not in results_df['file_name'].values: + file_path = os.path.join(asm_folder_path, asm_file) + feature_vector = preprocess_asm_file(file_path) + feature_vector = feature_vector.reshape(1, -1) + + # Predict using the current model + prediction = model_clf.predict(feature_vector) + probability = model_clf.predict_proba(feature_vector) + + mapped_prediction = class_mapping[prediction[0]] + predicted_prob = probability[0][prediction[0]] + + + if "XGB" in model_name.upper(): + new_predictions.append({ + 'file_name': asm_file, + 'prediction': mapped_prediction+1, + 'probability': predicted_prob + }) + else: + new_predictions.append({ + 'file_name': asm_file, + 'prediction': mapped_prediction, + 'probability': predicted_prob + }) + + # Append new predictions to results DataFrame + if new_predictions: + new_predictions_df = pd.DataFrame(new_predictions) + results_df = pd.concat([results_df, new_predictions_df], ignore_index=True) + results_df.to_csv(results_file_path, index=False) + + print(f"Predictions saved to {results_file_path}.") + try: + send_asm_predictions_to_api(results_file_path) + except: + print("Connection Failed") + + +def run_hex_conversion(): + hex_dirs = [d.strip() for d in hex_files_entry.get().split(',')] + hex_output_dir =bytes_output_directory + + if not hex_dirs or not hex_output_dir: + messagebox.showwarning("Warning", "Please specify both directories and output directory.") + return + + def hex_conversion_task(): + for hex_dir in hex_dirs: + hex_dir = hex_dir.strip() + if os.path.isdir(hex_dir): + scan_and_convert_directory(hex_dir, hex_output_dir) + else: + messagebox.showwarning("Warning", f"{hex_dir} is not a directory.") + + print("Hex conversion complete.") + run_malware_ai_analysis_bytes() + global isMonitoring + if(not isMonitoring): + isMonitoring = True + start_monitoring() + # hex_conversion_task() + threading.Thread(target=hex_conversion_task).start() + +def run_disassembly(): + start_dirs = [d.strip() for d in start_dirs_entry.get().split(',')] + output_dir = asm_output_directory + + if not start_dirs or not output_dir: + messagebox.showwarning("Warning", "Please specify both directories and output directory.") + return + + def disassembly_task(): + + process_files(output_dir, start_dirs) + run_malware_analysis_asm() + + global isMonitoring + if(not isMonitoring): + isMonitoring = True + start_monitoring() + # disassembly_task() + threading.Thread(target=disassembly_task).start() + +def start_monitoring(): + + directories = [d.strip() for d in hex_files_entry.get().split(',')] + directories += [d.strip() for d in start_dirs_entry.get().split(',')] + output_dir = output_directory + + def monitoring_task(): + monitor_directories(directories, output_dir) + + # Start monitoring in a new thread + threading.Thread(target=monitoring_task, daemon=True).start() + print("Started monitoring directories.") + +def on_closing(): + + root.destroy() + +def browse_hex_directories(): + directories = [] + while True: + directory = filedialog.askdirectory(title="Select a Directory") + if not directory: + break # Stop if no more directories are selected + directories.append(directory) + + if directories: + hex_files_entry.delete(0, tk.END) + hex_files_entry.insert(0, ', '.join(directories)) + +def browse_start_dirs(): + directories = [] + while True: + directory = filedialog.askdirectory(title="Select a Directory") + if not directory: + break # Stop if no more directories are selected + directories.append(directory) + + if directories: + start_dirs_entry.delete(0, tk.END) + start_dirs_entry.insert(0, ', '.join(directories)) + + +def malware_gui(parent_frame): + # Create a new window for malware analysis + malware_window = tk.Toplevel(parent_frame) + malware_window.title("Malware Analysis") + + # Add content to the malware window + tk.Label(malware_window, text="Malware Analysis Section", font=("Arial", 16)).pack(pady=20) + + # Add any additional widgets needed for malware analysis + tk.Label(malware_window, text="Select files for analysis:").pack(pady=5) + malware_files_entry = tk.Entry(malware_window, width=80) + malware_files_entry.pack(pady=5) + tk.Button(malware_window, text="Browse...", command=browse_hex_directories).pack(pady=5) + tk.Button(malware_window, text="Analyze Malware", command=lambda: print("Analyzing...")).pack(pady=10) + + +def is_auth(): + #hardware check + # Function to run device check before showing the wizard window + file_name = 'authenticated' + # Check if the file exists in the current directory + if os.path.isfile(file_name): + # Open and read the content + with open(file_name, 'r') as file: + content = file.read().strip() # Strip any extra whitespace or newline characters + + # Check if the content matches "Authenticated!" + if content == "Authenticated!": + return True # Flag to track if device check is completed + else: + return False + + +def device_check(): + + + if not is_auth(): + try: + subprocess.run(['python3', 'installer.py'], check=True) + device_check_completed = True # Set the flag once device check is complete + return True + except subprocess.CalledProcessError as e: + print(f"Error running device check script: {e}") + messagebox.showerror("Error", "Device check failed. The wizard will not start.") + return False + return True + +import tkinter as tk +from tkinter import ttk +# Requires `pip install ttkthemes` + +def create_wizard_window(): + global root + root = tk.Tk() + root.title("File Conversion and Disassembly Wizard") + root.geometry("700x450") + root.resizable(False, False) + + # Wizard frames with a more appealing color scheme + frame1 = tk.Frame(root, bg="#ffffff") + frame2 = tk.Frame(root, bg="#f9f9f9") + frame3 = tk.Frame(root, bg="#f9f9f9") + frame4 = tk.Frame(root, bg="#ffffff") + frame5 = tk.Frame(root, bg="#f9f9f9") + frame6 = tk.Frame(root, bg="#ffffff") + frames = [frame1, frame2, frame3, frame4, frame5, frame6] + + def show_frame(frame): + """Hide all frames and show only the specified one.""" + for frm in frames: + frm.pack_forget() + frame.pack(fill='both', expand=True) + + def update_progress(step): + """Update the progress bar and label to reflect the current step.""" + progress_label.config(text=f"Step {step} of 5") + progress_bar['value'] = (step / 5) * 100 + + # Enhanced Title Bar with Icons + title_frame = tk.Frame(root, bg="#283593") + title_frame.pack(fill="x", side="top") + + title_label = tk.Label( + title_frame, + text="🛠 Setup Wizard", + font=("Arial", 16, "bold"), + fg="white", + bg="#283593", + anchor="w", padx=20 + ) + title_label.pack(pady=10) + + # Progress bar with percentage display + progress_frame = tk.Frame(root, bg="#f0f0f0") + progress_frame.pack(fill="x", side="bottom") + progress_bar = ttk.Progressbar(progress_frame, orient="horizontal", mode="determinate", length=500) + progress_bar.pack(side="left", padx=20, pady=10) + progress_label = tk.Label(progress_frame, text="Step 1 of 5", font=("Arial", 12), bg="#f0f0f0") + progress_label.pack(side="left", padx=10) + + # Frame 1 - Welcome Screen + label1 = tk.Label(frame1, text="Welcome to the File Conversion Wizard", font=("Arial", 18, "bold"), bg="#ffffff") + label1.pack(pady=40) + desc_label1 = tk.Label(frame1, text="This wizard will guide you through the steps.", bg="#ffffff", font=("Arial", 12)) + desc_label1.pack(pady=10) + + next_button1 = ttk.Button(frame1, text="Next ➡️", command=lambda: [update_progress(2), show_frame(frame2)]) + next_button1.pack(pady=20) + + + # Frame 2 - Packet Capture Setup + label2 = tk.Label(frame2, text="📡 Packet Capture Setup", font=("Arial", 16, "bold"), bg="#f9f9f9") + label2.pack(pady=40) + setup_gui(frame2) # Assuming you have this function defined + + + button_frame2 = tk.Frame(frame2, bg="#f9f9f9") + button_frame2.pack(side="bottom", pady=10) + + next_button2 = ttk.Button(button_frame2, text="Next ➡️", command=lambda: [update_progress(3), show_frame(frame3)], width=10) + next_button2.pack(side="right", padx=10) + back_button2 = ttk.Button(button_frame2, text="⬅️ Back", command=lambda: [update_progress(1), show_frame(frame1)], width=10) + back_button2.pack(side="left", padx=10) + + # Frame 3 - Malware Analysis with Tabbed Layout + notebook = ttk.Notebook(frame3) + notebook.pack(fill='both', expand=True) + + hex_frame = ttk.Frame(notebook) + asm_frame = ttk.Frame(notebook) + notebook.add(hex_frame, text='🔢 Hex Conversion') + notebook.add(asm_frame, text='⚙️ ELF Disassembly') + + tk.Label(hex_frame, text="Select Directories to Convert to Hex:", font=("Arial", 12)).pack(pady=5) + global hex_files_entry + hex_files_entry = tk.Entry(hex_frame, width=80) + hex_files_entry.pack(pady=5) + tk.Button(hex_frame, text="Browse...",command=browse_hex_directories).pack(pady=5) + tk.Button(hex_frame, text="Convert to Hex", command=run_hex_conversion).pack(pady=10) + + tk.Label(asm_frame, text="Select Directories to Scan for ELF Files:", font=("Arial", 12)).pack(pady=5) + global start_dirs_entry + start_dirs_entry = tk.Entry(asm_frame, width=80) + start_dirs_entry.pack(pady=5) + tk.Button(asm_frame, text="Browse...",command=browse_start_dirs).pack(pady=5) + tk.Button(asm_frame, text="Disassemble ELF Files",command=run_disassembly).pack(pady=10) + + button_frame3 = tk.Frame(frame3, bg="#f9f9f9") + button_frame3.pack(side="bottom", pady=10) + next_button3 = ttk.Button(button_frame3, text="Next ➡️", command=lambda: [update_progress(4), show_frame(frame4)], width=10) + next_button3.pack(side="right", padx=10) + back_button3 = ttk.Button(button_frame3, text="⬅️ Back", command=lambda: [update_progress(2), show_frame(frame2)], width=10) + back_button3.pack(side="left", padx=10) + + # Frame 4 - Ransomware Detection + label4 = tk.Label(frame4, text="🛡️ Ransomware Detection", font=("Arial", 16, "bold"), bg="#f0f0f0", fg="#333") + label4.pack(pady=20) + + directory_frame = tk.Frame(frame4, bg="#f0f0f0") + directory_frame.pack(pady=10) + + selected_dir_label = tk.Label(directory_frame, text="No Directory Selected", width=50, bg="#f0f0f0", font=("Arial", 12), fg="#666") + selected_dir_label.grid(row=1, column=0, pady=10) + + def select_directory(): + directory = browse_directory() + if directory: + selected_dir_label.config(text=directory) + + browse_button = ttk.Button(directory_frame, text="Select Directory", command=select_directory) + browse_button.grid(row=0, column=0) + + status_label = tk.Label(frame4, text="", fg="blue", bg="#f0f0f0") + status_label.pack(pady=10) + + run_button = ttk.Button(frame4, text="Run Predictions", command=lambda: run_predictions(selected_dir_label.cget("text"), status_label)) + run_button.pack(pady=10) + + button_frame4 = tk.Frame(frame4, bg="#f0f0f0") + button_frame4.pack(side="bottom", pady=15) + + next_button4 = ttk.Button(button_frame4, text="Next ➡️", command=lambda: [update_progress(5), show_frame(frame5)], width=10) + next_button4.pack(side="right", padx=10) + back_button4 = ttk.Button(button_frame4, text="⬅️ Back", command=lambda: [update_progress(3), show_frame(frame3)], width=10) + back_button4.pack(side="left", padx=10) + + # Frame 5 - AuditD Manager + label5 = tk.Label(frame5, text="🔍 AuditD Manager", font=("Arial", 16, "bold"), bg="#f0f0f0", fg="#333") + label5.pack(pady=20) + + # Placeholder for AuditD Manager + AuditDManagerApp(frame5) # Uncomment and define if AuditDManagerApp is available + + + button_frame5 = tk.Frame(frame5, bg="#f0f0f0") + button_frame5.pack(side="bottom", pady=15) + + next_button5 = ttk.Button(button_frame5, text="Next ➡️", command=lambda: show_frame(frame6), width=10) + next_button5.pack(side="right", padx=10) + back_button5 = ttk.Button(button_frame5, text="⬅️ Back", command=lambda: [update_progress(4), show_frame(frame4)], width=10) + back_button5.pack(side="left", padx=10) + + # Frame 6 - Completion Screen + label6 = tk.Label(frame6, text="🎉 Setup Complete!", font=("Arial", 18, "bold"), bg="#ffffff") + label6.pack(pady=40) + desc_label6 = tk.Label(frame6, text="Thank you for using the setup wizard.", bg="#ffffff", font=("Arial", 12)) + desc_label6.pack(pady=10) + finish_button = ttk.Button(frame6, text="➡️ Finish ⬅️", command=root.quit, width=10) + finish_button.pack(pady=10) + + # Show the first frame + show_frame(frame1) + root.mainloop() + +def on_closing(): + root.quit() + +if device_check(): + # If device check is successful, initialize the Tkinter window + create_wizard_window() +else: + # If the device check fails, show an error message and exit + print("Device check failed. Exiting program.") + messagebox.showerror("Error", "Device check failed. The wizard will not start.") + + + + + + + + +# def create_wizard_window(): +# global root +# root = tk.Tk() +# root.title("File Conversion and Disassembly Wizard") +# root.geometry("600x400") +# root.resizable(False, False) + +# # Wizard frames +# frame1 = tk.Frame(root, bg="#f0f0f0") +# frame2 = tk.Frame(root, bg="#f0f0f0") +# frame3 = tk.Frame(root, bg="#f0f0f0") +# frame4 = tk.Frame(root, bg="#f0f0f0") +# frame5 = tk.Frame(root, bg="#f0f0f0") +# frame6 = tk.Frame(root, bg="#f0f0f0") + +# frames = [frame1, frame2, frame3, frame4, frame5, frame6] + +# current_step = 1 + +# def show_frame(frame): +# """Hide all frames and show only the specified one.""" +# for frm in frames: +# frm.pack_forget() +# frame.pack(fill='both', expand=True) + +# def update_progress(step): +# """Update the progress bar and label to reflect the current step.""" +# progress_label.config(text=f"Step {step} of 5") +# progress_bar['value'] = (step / 5) * 100 + +# # Title bar frame for better aesthetics +# title_frame = tk.Frame(root, bg="#0078d7") +# title_frame.pack(fill="x", side="top") + +# title_label = tk.Label(title_frame, text="Setup Wizard", font=("Arial", 14, "bold"), fg="white", bg="#0078d7") +# title_label.pack(pady=10) + +# # Progress bar +# progress_bar = ttk.Progressbar(root, orient="horizontal", mode="determinate", length=400) +# progress_bar.pack(side="bottom", pady=10) + +# progress_label = tk.Label(root, text="Step 1 of 5", font=("Arial", 12)) +# progress_label.pack(side="bottom") + +# # Frame 1 - Welcome Screen +# label1 = tk.Label(frame1, text="Welcome to the File Conversion Wizard", font=("Arial", 16), bg="#f0f0f0") +# label1.pack(pady=40) +# desc_label1 = tk.Label(frame1, text="This wizard will guide you through the steps.", bg="#f0f0f0", font=("Arial", 12)) +# desc_label1.pack(pady=10) + +# next_button1 = ttk.Button(frame1, text="Next", command=lambda: [update_progress(2), show_frame(frame2)]) +# next_button1.pack(pady=10, side="bottom") + +# # Frame 2 - Packet Capture UI +# label2 = tk.Label(frame2, text="Packet Capture Setup", font=("Arial", 16), bg="#f0f0f0") +# label2.pack(pady=40) + +# # Insert your packet capture setup UI here +# setup_gui(frame2) # Assuming you have this function defined + +# button_frame2 = tk.Frame(frame2, bg="#f0f0f0") +# button_frame2.pack(side="bottom", pady=10) + +# next_button2 = ttk.Button(button_frame2, text="Next", command=lambda: [update_progress(3), show_frame(frame3)], width=10) +# next_button2.pack(side="right", padx=10) + +# back_button2 = ttk.Button(button_frame2, text="Back", command=lambda: [update_progress(1), show_frame(frame1)], width=10) +# back_button2.pack(side="left", padx=10) + +# # Frame 3 - Malware Analysis +# notebook = ttk.Notebook(frame3) +# notebook.pack(fill='both', expand=True) + +# hex_frame = ttk.Frame(notebook) +# asm_frame = ttk.Frame(notebook) +# notebook.add(hex_frame, text='Hex Conversion') +# notebook.add(asm_frame, text='ELF Disassembly') + +# tk.Label(hex_frame, text="Select Directories to Convert to Hex:", font=("Arial", 12)).pack(pady=5) +# global hex_files_entry +# hex_files_entry = tk.Entry(hex_frame, width=80) +# hex_files_entry.pack(pady=5) +# tk.Button(hex_frame, text="Browse...",command=browse_hex_directories).pack(pady=5) +# tk.Button(hex_frame, text="Convert to Hex",command=run_hex_conversion).pack(pady=10) + +# tk.Label(asm_frame, text="Select Directories to Scan for ELF Files:", font=("Arial", 12)).pack(pady=5) +# global start_dirs_entry +# start_dirs_entry = tk.Entry(asm_frame, width=80) +# start_dirs_entry.pack(pady=5) +# tk.Button(asm_frame, text="Browse...", command=browse_start_dirs).pack(pady=5) +# tk.Button(asm_frame, text="Disassemble ELF Files",command=run_disassembly).pack(pady=10) + +# button_frame3 = tk.Frame(frame3, bg="#f0f0f0") +# button_frame3.pack(side="bottom", pady=10) + +# next_button3 = ttk.Button(button_frame3, text="Next", command=lambda: [update_progress(4), show_frame(frame4)], width=10) +# next_button3.pack(side="right", padx=10) + +# back_button3 = ttk.Button(button_frame3, text="Back", command=lambda: [update_progress(2), show_frame(frame2)], width=10) +# back_button3.pack(side="left", padx=10) + +# # Frame 4 - Ransomware Detection +# label4 = tk.Label(frame4, text="Ransomware Detection", font=("Arial", 16), bg="#f0f0f0") +# label4.pack(pady=40) + +# directory_frame = tk.Frame(frame4, bg="#f0f0f0") +# directory_frame.pack(pady=10) + +# selected_dir_label = tk.Label(directory_frame, text="No Directory Selected", width=40, bg="#f0f0f0") +# selected_dir_label.grid(row=1, column=0) + +# # Directory label + + +# def select_directory(): +# directory = browse_directory() +# if directory: +# selected_dir_label.config(text=directory) +# # Start the watchdog observer + +# browse_button = ttk.Button(directory_frame, text="Select Directory", command=select_directory) +# browse_button.grid(row=0, column=0) + +# status_label = tk.Label(frame4, text="", fg="blue", bg="#f0f0f0") +# status_label.pack(pady=10) + +# run_button = ttk.Button(frame4, text="Run Predictions", command=lambda: run_predictions(selected_dir_label.cget("text"), status_label)) +# run_button.pack(pady=10) + +# button_frame4 = tk.Frame(frame4, bg="#f0f0f0") +# button_frame4.pack(side="bottom", pady=10) + +# next_button4 = ttk.Button(button_frame4, text="Next", command=lambda: [update_progress(5), show_frame(frame5)], width=10) +# next_button4.pack(side="right", padx=10) + +# back_button4 = ttk.Button(button_frame4, text="Back", command=lambda: [update_progress(3), show_frame(frame3)], width=10) +# back_button4.pack(side="left", padx=10) + +# # Frame 5 - AuditD Manager +# audit_app = AuditDManagerApp(frame5) +# audit_app.frame.pack(fill='both', expand=True) + +# # tk.Label(frame5, text="AuditD Manager", font=("Arial", 16), bg="#f0f0f0").pack(pady=40) + + +# button_frame5 = tk.Frame(frame5, bg="#f0f0f0") +# button_frame5.pack(side="bottom", pady=10) + +# next_button5 = ttk.Button(button_frame5, text="Next", command=lambda: show_frame(frame6), width=10) +# next_button5.pack(side="right", padx=10) + +# back_button5 = ttk.Button(button_frame5, text="Back", command=lambda: [update_progress(4), show_frame(frame4)], width=10) +# back_button5.pack(side="left", padx=10) + +# # Frame 6 - Summary +# label6 = tk.Label(frame6, text="Setup Complete!", font=("Arial", 16), bg="#f0f0f0") +# label6.pack(pady=40) +# desc_label6 = tk.Label(frame6, text="Thank you for using the setup wizard.", bg="#f0f0f0", font=("Arial", 12)) +# desc_label6.pack(pady=10) + +# finish_button = ttk.Button(frame6, text="Finish", command=root.quit, width=10) +# finish_button.pack(pady=10) + +# # Show the first frame +# show_frame(frame1) + +# root.mainloop() + + +# def on_closing(): +# root.quit() + +# if __name__ == "__main__": + +# root = tk.Tk() +# create_wizard_window() + + + diff --git a/installer.py b/installer.py new file mode 100644 index 0000000..eb31cb8 --- /dev/null +++ b/installer.py @@ -0,0 +1,270 @@ + +import tkinter as tk +from tkinter import messagebox +import re +import webbrowser +import requests # Make sure to install this library if you haven't already + + + + +# Function to get the device MAC address +def get_mac_address(): + return '13:bb:81:47:b2:e6' + +# Function to generate a 16-digit unique ID +def get_unique_id(): + return 'cf4650bb871111ef' + +# Function to handle the "Check Device" button +def check_device(): + response = messagebox.askyesno("Check Device", "Do you want to check your device?") + if response: # User clicked "Yes" + email_label.pack() + email_entry.pack() + submit_button.pack() + +# Function to validate and submit the entered email and call the send-otp API +def submit_email(): + email = email_entry.get() + if re.match(r"[^@]+@[^@]+\.[^@]+", email): # Simple email validation + messagebox.showinfo("Success", f"Email submitted: {email}") + with open('authenticated', 'w') as flag: + flag.write('Authenticated!') + + # Replace 'your_api_url' with the actual URL of your API + api_url = 'http://127.0.0.1:8000/send-otp/' + try: + response = requests.post(api_url, data={"email": email}) # Adjust the payload as needed + if response.status_code == 200: + messagebox.showinfo("Success", "OTP sent successfully! Please verify OTP on the web.") + webbrowser.open('http://127.0.0.1:8000/signup') + + # Show OTP verification window after successful OTP request + show_otp_verification_window(email) + else: + messagebox.showwarning("Error", "Failed to send OTP.") + except Exception as e: + messagebox.showerror("Error", f"An error occurred: {str(e)}") + else: + messagebox.showwarning("Error", "Invalid email entered") + +# Function to show OTP verification window +def show_otp_verification_window(email): + otp_window = tk.Toplevel(root) + otp_window.title("Verify OTP") + otp_window.geometry("300x200") + + otp_label = tk.Label(otp_window, text="Enter the OTP:") + otp_label.pack(pady=10) + + # Entry field for OTP + otp_entry = tk.Entry(otp_window) + otp_entry.pack(pady=10) + + # Button to verify OTP + verify_button = tk.Button(otp_window, text="Verify OTP", command=lambda: verify_otp(otp_entry.get(), email, otp_window)) + verify_button.pack(pady=10) + + # Focus on the OTP entry field + otp_entry.focus_set() + +def verify_otp(otp, email, window): + api_url = 'http://127.0.0.1:8000/verify-second-otp/' + try: + # Include the second_otp and email in the payload + response = requests.post(api_url, data={ + "second_otp": otp, + + }) + + if response.status_code == 200: + # Extract user_profile_id from the response + response_data = response.json() + user_profile_id = response_data.get("user_profile_id") + + messagebox.showinfo("Success", "OTP verified successfully!") + + window.destroy() # Close OTP window on successful verification + + # After OTP is verified, send device info with user_profile_id + send_device_info(user_profile_id) + + else: + messagebox.showwarning("Error", "Invalid or expired OTP.") + except Exception as e: + messagebox.showerror("Error", f"An error occurred: {str(e)}") + +# Function to send the device information after OTP is verified +def send_device_info(user_profile_id): + device_info_url = 'http://127.0.0.1:8000/send-device-info/' # Adjust to the correct API endpoint + mac_address = get_mac_address() # Get MAC address + unique_id = get_unique_id() # Get unique ID + + try: + # Make the POST request to send the device info + response = requests.post(device_info_url, json={ + "user_profile_id": user_profile_id, # Use the user_profile_id from OTP verification + "mac_address": mac_address, + "unique_id": unique_id + }) + + if response.status_code == 200: + + messagebox.showinfo("Success", "Device info sent successfully!") + webbrowser.open('http://127.0.0.1:8000/home') + root.destroy() + else: + messagebox.showwarning("Error", f"Failed to send device info. {response.json().get('error')}") + + except Exception as e: + messagebox.showerror("Error", f"An error occurred while sending device info: {str(e)}") + +# Create the main window +root = tk.Tk() +root.title("Device Info Checker") +root.geometry("300x300") + +# Create and pack the button to check the device +check_button = tk.Button(root, text="Check Device", command=check_device) +check_button.pack(pady=20) + +# Label and entry for email input (hidden initially) +email_label = tk.Label(root, text="Enter your email:") +email_entry = tk.Entry(root) +submit_button = tk.Button(root, text="Submit", command=submit_email) + + +# Run the GUI loop +root.mainloop() +#===========================================================================this is working ============================= +# import webview +# import tkinter as tk +# from tkinter import messagebox +# import requests + +# # Function to get the device MAC address +# def get_mac_address(): +# return '13:bb:81:47:b2:e6' + +# # Function to generate a 16-digit unique ID +# def get_unique_id(): +# return 'cf4650bb871111ef' + +# # Function to handle the "Check Device" button +# def check_device(): +# response = messagebox.askyesno("Check Device", "Do you want to check your device?") +# if response: # User clicked "Yes" +# email_label.pack() +# email_entry.pack() +# submit_button.pack() + +# # Function to validate and submit the entered email and call the send-otp API +# def submit_email(): +# email = email_entry.get() +# if '@' in email: # Simple email validation +# messagebox.showinfo("Success", f"Email submitted: {email}") +# api_url = 'http://127.0.0.1:8000/send-otp/' # Replace with your actual API URL + +# try: +# response = requests.post(api_url, data={"email": email}) +# if response.status_code == 200: +# messagebox.showinfo("Success", "OTP sent successfully! Please verify OTP on the web.") +# # Show OTP verification window using PyWebView +# show_otp_verification_window(email) +# else: +# messagebox.showwarning("Error", "Failed to send OTP.") +# except Exception as e: +# messagebox.showerror("Error", f"An error occurred: {str(e)}") +# else: +# messagebox.showwarning("Error", "Invalid email entered") + +# # Function to show OTP verification window using PyWebView +# def show_otp_verification_window(email): +# # HTML content to show the OTP input window +# html_content = f""" +# +# +# +# +# +# OTP Verification +# +# +# +#

Verify OTP

+#

Please enter the OTP sent to {email}

+# +# +#

+ +# +# +# +# """ + +# # Create a PyWebView window +# webview.create_window('OTP Verification', html=html_content, js_api=JSApi()) +# webview.start() + +# # Define a JavaScript API class that will handle Python calls from the web page +# class JSApi: +# def verify_otp(self, otp, email): +# # Verify OTP with the backend +# api_url = 'http://127.0.0.1:8000/verify-second-otp/' +# try: +# response = requests.post(api_url, data={"second_otp": otp, "email": email}) +# if response.status_code == 200: +# return {"message": "OTP verified successfully!"} +# else: +# return {"message": "Invalid or expired OTP."} +# except Exception as e: +# return {"message": f"An error occurred: {str(e)}"} + +# # Create the main window +# root = tk.Tk() +# root.title("Device Info Checker") +# root.geometry("300x300") + +# # Create and pack the button to check the device +# check_button = tk.Button(root, text="Check Device", command=check_device) +# check_button.pack(pady=20) + +# # Label and entry for email input (hidden initially) +# email_label = tk.Label(root, text="Enter your email:") +# email_entry = tk.Entry(root) +# submit_button = tk.Button(root, text="Submit", command=submit_email) + +# # Run the GUI loop +# root.mainloop()