Update neurolyzer.py

Realistic MAC Address Generation

    Improvement: The updated version uses a more realistic MAC address by incorporating an OUI (Organizationally Unique Identifier) and randomizing the last three bytes within a restricted range.

    Flexible Randomization Interval

    Improvement: The randomization interval is now flexible, varying between 30 minutes and 2 hours. Randomizing the interval adds unpredictability, making the MAC address changes harder to detect. This increases stealth.

    Improved MAC Randomization for Monitor Mode

    Improvement: When the Wi-Fi interface is in monitor mode, the plugin temporarily switches to managed mode to change the MAC address and restores monitor mode afterward.

    Updated UI Handling

    Improvement: The UI is now updated more effectively by directly modifying the value attribute of the UI components in on_ui_update().

    Better Error Handling and Logging

    Improvement: The plugin now has enhanced error handling for subprocess calls, such as bringing the interface down or changing the MAC address. More detailed logs are provided for different stages.

    Initial MAC Address Randomization

    Improvement: The plugin now performs an initial MAC address randomization when it is loaded (self.randomize_mac() in on_loaded()). This ensures that the device's MAC address is randomized as soon as the plugin starts, providing enhanced privacy from the start.

    Time-Dependent MAC Randomization

    Improvement: The next MAC address change time is now dynamically calculated based on the random interval. This ensures the MAC address change schedule follows the random interval, making it harder to predict.
This commit is contained in:
AlienMajik
2025-02-20 03:20:03 -08:00
committed by GitHub
parent 5434c014f4
commit d407590b62

View File

@ -1,6 +1,7 @@
import logging
import subprocess
import time
import random
import pwnagotchi.plugins as plugins
from pwnagotchi.ui.components import LabeledValue
@ -9,9 +10,9 @@ import pwnagotchi.ui.fonts as fonts
class Neurolyzer(plugins.Plugin):
__author__ = 'AlienMajik'
__version__ = '1.1.1'
__version__ = '1.5.1'
__license__ = 'GPL3'
__description__ = "A plugin for enhanced stealth and privacy."
__description__ = "A plugin for enhanced stealth and privacy using realistic OUIs."
def __init__(self):
self.enabled = False
@ -19,6 +20,9 @@ class Neurolyzer(plugins.Plugin):
self.operation_mode = 'stealth' # 'normal' or 'stealth'
self.mac_change_interval = 3600 # Interval in seconds
self.last_mac_change_time = time.time()
self.next_mac_change_time = self.last_mac_change_time + self.mac_change_interval
self.last_random_mac = None
# UI custom positions
self.mode_label_position = (0, 0)
self.next_mac_change_label_position = (0, 0)
@ -28,9 +32,17 @@ class Neurolyzer(plugins.Plugin):
self.wifi_interface = self.options.get('wifi_interface', 'wlan0')
self.operation_mode = self.options.get('operation_mode', 'stealth')
self.mac_change_interval = self.options.get('mac_change_interval', 3600)
self.next_mac_change_time = time.time() + self.mac_change_interval
# UI positions from config
self.mode_label_position = (self.options.get('mode_label_x', 0), self.options.get('mode_label_y', 0))
self.next_mac_change_label_position = (self.options.get('next_mac_change_label_x', 0), self.options.get('next_mac_change_label_y', 10))
self.mode_label_position = (
self.options.get('mode_label_x', 0),
self.options.get('mode_label_y', 0)
)
self.next_mac_change_label_position = (
self.options.get('next_mac_change_label_x', 0),
self.options.get('next_mac_change_label_y', 10)
)
if self.enabled:
logging.info("[Neurolyzer] Plugin loaded. Operating in %s mode." % self.operation_mode)
@ -66,24 +78,99 @@ class Neurolyzer(plugins.Plugin):
if not self.enabled:
return
remaining_time = self.mac_change_interval - (time.time() - self.last_mac_change_time)
self.next_mac_change_label.set(
"%dm" % (remaining_time // 60)
)
self.mode_label.set(self.operation_mode.capitalize())
remaining_time = self.next_mac_change_time - time.time()
if remaining_time <= 0:
self.randomize_mac()
self.next_mac_change_time = time.time() + self.randomize_interval()
# Update UI labels by directly setting the value attribute.
self.next_mac_change_label.value = "%dm" % (remaining_time // 60)
self.mode_label.value = self.operation_mode.capitalize()
def randomize_mac(self):
if self.operation_mode != 'stealth' or not self.enabled:
return
try:
subprocess.run(['macchanger', '-r', self.wifi_interface], check=True)
self.last_mac_change_time = time.time()
logging.info(f"[Neurolyzer] MAC address randomized for {self.wifi_interface}.")
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] MAC randomization failed: {e}")
new_mac = self.generate_realistic_mac()
if 'mon' in self.wifi_interface.lower():
# For monitor mode interfaces, switch temporarily to managed mode.
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'down'],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.warning(f"[Neurolyzer] Failed to bring down interface {self.wifi_interface}: {e}")
try:
subprocess.run(['sudo', 'iwconfig', self.wifi_interface, 'mode', 'managed'],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] Failed to set {self.wifi_interface} to managed mode: {e}")
return
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'address', new_mac],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] MAC address change failed: {e}")
return
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'up'],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] Failed to bring up interface {self.wifi_interface}: {e}")
return
# Optionally, switch back to monitor mode if needed:
# try:
# subprocess.run(['iwconfig', self.wifi_interface, 'mode', 'monitor'],
# check=True, stderr=subprocess.DEVNULL)
# except subprocess.CalledProcessError as e:
# logging.warning(f"[Neurolyzer] Failed to set {self.wifi_interface} back to monitor mode: {e}")
else:
# For non-monitor mode interfaces, use the standard sequence.
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'down'],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.warning(f"[Neurolyzer] Failed to bring down interface {self.wifi_interface}: {e}")
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'address', new_mac],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] MAC address change failed: {e}")
return
try:
subprocess.run(['sudo', 'ip', 'link', 'set', 'dev', self.wifi_interface, 'up'],
check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
logging.error(f"[Neurolyzer] Failed to bring up interface {self.wifi_interface}: {e}")
return
self.last_mac_change_time = time.time()
self.last_random_mac = new_mac
logging.info(f"[Neurolyzer] MAC address changed to {new_mac} for {self.wifi_interface}.")
def generate_realistic_mac(self):
"""Generate a stealthy MAC address with a less identifiable OUI."""
mac = [
0x00, 0x25, 0x96,
random.randint(0x00, 0x7F),
random.randint(0x00, 0x7F),
random.randint(0x00, 0x7F)
]
mac_address = ':'.join(f"{byte:02x}" for byte in mac)
return mac_address
def randomize_interval(self):
"""Return a random interval between 30 minutes and 2 hours."""
return random.randint(1800, 7200)
def on_unload(self):
if not self.enabled:
return
logging.info("[Neurolyzer] Plugin unloaded.")