diff --git a/wifite/tools/dependency.py b/wifite/tools/dependency.py index 0ff613fd0..a89a62dc0 100644 --- a/wifite/tools/dependency.py +++ b/wifite/tools/dependency.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import os +import shlex import shutil import subprocess @@ -79,7 +80,7 @@ def install(cls, package_name): return False, 'No supported package manager found' try: result = subprocess.run( - cmd, shell=True, capture_output=True, text=True, timeout=300 + shlex.split(cmd), shell=False, capture_output=True, text=True, timeout=300 ) output = (result.stdout + '\n' + result.stderr).strip() return result.returncode == 0, output diff --git a/wifite/util/color.py b/wifite/util/color.py index 5d5ec3ccf..2f65fc1db 100755 --- a/wifite/util/color.py +++ b/wifite/util/color.py @@ -78,9 +78,9 @@ def clear_line(): @staticmethod def clear_entire_line(): - import os - (rows, columns) = os.popen('stty size', 'r').read().split() - Color.p('\r' + (' ' * int(columns)) + '\r') + import shutil + columns = shutil.get_terminal_size(fallback=(80, 24)).columns + Color.p('\r' + (' ' * columns) + '\r') @staticmethod def pattack(attack_type, target, attack_name, progress): diff --git a/wifite/util/logger.py b/wifite/util/logger.py index 9e1516891..c10c7b8b1 100755 --- a/wifite/util/logger.py +++ b/wifite/util/logger.py @@ -101,6 +101,10 @@ def _sanitize_message(cls, message: str) -> str: - Known wpa-sec API key from Configuration.wpasec_api_key - Command-line API key arguments like "-k " and "--key " - MAC addresses in standard hex notation (aa:bb:cc:dd:ee:ff) + - WPA/WEP keys from aircrack "KEY FOUND! [ ]" output + - Live passphrase progress "Current passphrase: " + - Hashcat cracked output "hash*bssid*station*essid:" + - Generic PSK/passphrase/password keyword-value pairs """ try: # Import lazily to avoid circular imports during module initialization @@ -121,10 +125,10 @@ def _sanitize_message(cls, message: str) -> str: # Never let sanitization break logging pass + import re + # Mask common CLI key patterns: "-k " and "--key " try: - import re - def _mask_cli_key(match): flag = match.group(1) return f"{flag} ****" @@ -136,8 +140,6 @@ def _mask_cli_key(match): # Mask MAC addresses: aa:bb:cc:dd:ee:ff -> aa:bb:cc:**:**:** try: - import re - def _mask_mac(match): full = match.group(0) parts = full.split(":") @@ -149,6 +151,46 @@ def _mask_mac(match): except Exception: pass + # Mask aircrack "KEY FOUND! [ ]" output + try: + sanitized = re.sub(r"(KEY FOUND!\s*\[)\s*\S.*?\s*(\])", r"\1 **** \2", sanitized) + except Exception: + pass + + # Mask aircrack live progress "Current passphrase: " + try: + sanitized = re.sub( + r"(Current\s+passphrase\s*:)\s*\S.*", + r"\1 ****", + sanitized, + flags=re.IGNORECASE, + ) + except Exception: + pass + + # Mask hashcat cracked output: trailing : after PMKID/hash lines + # Format: hash*bssid*station*essid:password or hash:password + try: + sanitized = re.sub( + r"([0-9a-fA-F\*]{20,}:[^:\n]{0,64}):[^\n]+$", + r"\1:****", + sanitized, + flags=re.MULTILINE, + ) + except Exception: + pass + + # Mask generic keyword-value pairs: password/passphrase/psk followed by + # a delimiter (=, :, space) and a value + try: + sanitized = re.sub( + r"(?i)(password|passphrase|psk|wpa_psk|wpa_passphrase)\s*[=:]\s*\S+", + r"\1=****", + sanitized, + ) + except Exception: + pass + return sanitized @classmethod diff --git a/wifite/util/scanner.py b/wifite/util/scanner.py index 66f7b4585..ed829c7f3 100644 --- a/wifite/util/scanner.py +++ b/wifite/util/scanner.py @@ -218,10 +218,10 @@ def found_target(self): @staticmethod def clr_scr(): import platform - import os + import subprocess cmdtorun = 'cls' if platform.system().lower() == "windows" else 'clear' - os.system(shlex_quote(cmdtorun)) + subprocess.run([cmdtorun], check=False) def print_targets(self): """Prints targets selection menu (1 target per row).""" @@ -290,15 +290,13 @@ def print_targets(self): @staticmethod def get_terminal_height(): - import os - (rows, columns) = os.popen('stty size', 'r').read().split() - return int(rows) + import shutil + return shutil.get_terminal_size(fallback=(24, 80)).lines @staticmethod def get_terminal_width(): - import os - (rows, columns) = os.popen('stty size', 'r').read().split() - return int(columns) + import shutil + return shutil.get_terminal_size(fallback=(24, 80)).columns def select_targets(self): """