diff --git a/modules/stealth/mac_manager.py b/modules/stealth/mac_manager.py index 8a2240a..63e1fa1 100644 --- a/modules/stealth/mac_manager.py +++ b/modules/stealth/mac_manager.py @@ -11,6 +11,7 @@ import json import logging import os import random +import socket import sqlite3 import time from pathlib import Path @@ -58,6 +59,7 @@ class MacManager(BaseModule): self._wifi_iface: Optional[str] = None self._original_eth_mac: Optional[str] = None self._original_wifi_mac: Optional[str] = None + self._original_hostname: Optional[str] = None self._db_path = self._resolve_db_path() # ------------------------------------------------------------------ @@ -90,6 +92,8 @@ class MacManager(BaseModule): except Exception: pass + self._original_hostname = socket.gethostname() + # Select and apply profile self._profile = self._select_profile() if self._profile is None: @@ -131,6 +135,18 @@ class MacManager(BaseModule): logger.warning("Failed to restore original MAC: %s", exc) self._cleanup_dhclient_conf() + + if self._original_hostname: + try: + import subprocess + subprocess.run( + ["hostnamectl", "set-hostname", self._original_hostname], + check=True, capture_output=True, + ) + logger.debug("Hostname restored to %s", self._original_hostname) + except Exception: + pass + self._running = False self.state.set_module_status(self.name, "stopped") logger.info("MacManager stopped — original MACs restored") @@ -145,6 +161,8 @@ class MacManager(BaseModule): base["profile_name"] = self._profile.get("device_name", "unknown") base["applied_mac"] = self._profile.get("applied_mac", "unknown") base["dhcp_hostname"] = self._profile.get("dhcp_hostname", "unknown") + if self._profile.get("applied_hostname"): + base["applied_hostname"] = self._profile["applied_hostname"] if self._eth_iface: try: base["current_eth_mac"] = get_mac(self._eth_iface) @@ -304,6 +322,8 @@ class MacManager(BaseModule): logger.debug("TCP stack: TTL=%d, window=%d", ttl, tcp_win) + self._set_system_hostname(profile) + def _write_dhclient_conf(self, profile: dict) -> None: """Write dhclient.conf with hostname + vendor class matching the profile.""" hostname = profile.get("dhcp_hostname", "localhost") @@ -327,6 +347,24 @@ class MacManager(BaseModule): except (IOError, PermissionError) as exc: logger.warning("Failed to write dhclient.conf: %s", exc) + def _set_system_hostname(self, profile: dict) -> None: + """Set system hostname to match the device profile for full fingerprint consistency.""" + import subprocess + hostname = profile.get("dhcp_hostname", "") + if not hostname: + return + suffix = "".join(f"{random.randint(0, 15):x}" for _ in range(4)) + new_hostname = f"{hostname}-{suffix}" + try: + subprocess.run( + ["hostnamectl", "set-hostname", new_hostname], + check=True, capture_output=True, + ) + profile["applied_hostname"] = new_hostname + logger.info("System hostname set to %s", new_hostname) + except Exception as exc: + logger.warning("Failed to set hostname: %s", exc) + def _cleanup_dhclient_conf(self) -> None: """Remove our DHCP config on clean exit.""" conf_file = "/etc/dhcp/dhclient.conf.d/bb-profile.conf"