Commit Graph

139 Commits

Author SHA1 Message Date
Cobra 61a1756dae Fix mktemp overwrite prompt in autossh tunnel keygen 2026-04-07 15:56:59 -04:00
Cobra 56ad5662ac Fix ssh-keygen overwrite prompt and key landing in root home
mktemp creates the file before ssh-keygen runs — keygen sees it exists
and prompts. Switch to mktemp -d so keygen writes a fresh file.

When run via sudo SUDO_USER is set but HOME=/root. Resolve the real
home via getent so the key lands in the operator's ~/.ssh, not root's.
2026-04-07 15:47:31 -04:00
Cobra 6cb48909b2 Save generated SSH key locally to ~/.ssh/bb-<device_id>
Infisical is the backup copy. Local key at a predictable path means
no hunting — ssh -i ~/.ssh/bb-<device_id> just works.
2026-04-07 15:22:55 -04:00
Cobra 42c05f37e6 Fix ANSI rendering and Infisical key storage in operator wizard
echo calls in summary/final sections were missing -e flag so ANSI
escape codes printed literally instead of rendering.

Infisical SSH key storage was targeting a non-existent 'bigbrother'
folder, silently failing to store the private key. Removed folder
argument so keys store at root where creds CLI can retrieve them.
2026-04-07 15:22:16 -04:00
Cobra e00769631a Remove homeserver default — no infrastructure fingerprints in wizard 2026-04-07 14:56:46 -04:00
Cobra 4c332eabb4 Proper Matrix alerter support with client API
Matrix doesn't use a simple webhook URL — needs homeserver, room ID,
and bot token separately. Uses PUT /_matrix/client/v3/rooms/.../send
with Bearer token auth. Room ID is bash-encoded (! → %21, : → %3A)
to avoid Python dependency pre-setup. Also adds ntfy and plain
webhook as options under a typed alerter menu.
2026-04-07 14:55:23 -04:00
Cobra 84f0775f76 Align device ID with MAC profile OUI for consistent network identity
Device ID is now a MAC-format hex string (12 chars) using the same
OUI as the randomly selected device profile. If the device gets an
Amazon OUI for its MAC, the device ID starts with fc65de. Hostname,
MAC, and device ID all point to the same vendor — no inconsistency
for anyone watching the network.
2026-04-07 14:48:22 -04:00
Cobra d8de49a53d Remove bb- prefix from device ID default
bb- prefix is a tool fingerprint — visible in Infisical key names,
alerter payloads, and config files on the device. Default is now
a plain 10-char hex string with no identifying prefix.
2026-04-07 14:44:59 -04:00
Cobra af124cc6d0 Default VPN to Tailscale, add auth key expiry warning
Tailscale handles NAT traversal automatically via DERP relay — more
reliable than WireGuard for devices landing on unknown networks.
Add reminder to use reusable non-expiring keys for long-term drops.
2026-04-07 14:41:17 -04:00
Cobra b0fb5af1fb Include device IP and hostname in firstboot alerter beacon
Blind drops need some way to locate the device when no VPN is selected.
Alerter now reports public IP (via ipify) with fallback to local IP,
plus hostname — gives enough info to SSH directly on same-network drops.
2026-04-07 14:37:04 -04:00
Cobra 2b00b28de6 Add reverse SSH tunnel (autossh) as VPN option in operator wizard
Generates a dedicated tunnel keypair during setup, prints public key
for operator to pre-stage on server, writes private key to SD card.
On first boot: installs autossh, writes bb-tunnel.service with
correct RemoteForward and reconnect settings. Zero network traffic
until operator initiates connection through the tunnel port.
2026-04-07 14:30:10 -04:00
Cobra ae79d64913 Align default hostname with MAC device profiles for OPSEC consistency 2026-04-07 14:19:55 -04:00
Cobra 2b53da80d0 Fix wizard: defaults for all prompts, random hostname/device-id, download robustness
- Add prompt_default() helper: shows defaults, accepts Enter to use them
- WiFi: default=n (skip), keeps passphrase prompt loop
- Root password: auto-generate with openssl, show in summary if used, operator can override
- SSH key: default=1 (generate new)
- Device ID: auto-generate bb-<8-char-uuid>
- Boot mode: default=1 (passive)
- VPN: default=1 (none)
- Hostname: NEW section with auto-generated node-<6-char-uuid> default
- Alerter: default=n (disabled)
- Download: use curl -L (no -f), verify file exists and >50MB
- Config summary: show hostname, mask password (show auto-generated clearly)
- Apply config: write BB_HOSTNAME to /etc/hostname and /etc/hosts
- No eval with user input: use printf -v for variable assignment
2026-04-07 14:17:01 -04:00
Cobra ae35f3f7b8 Fix HOME path when run via sudo — use SUDO_USER's home not /root 2026-04-07 14:12:07 -04:00
Cobra 6f2a6dacea Fix SCRIPT_DIR path now that operator_setup.sh is at repo root 2026-04-07 14:05:36 -04:00
Cobra 8e7e3fe91d Move operator_setup.sh to repo root for direct access 2026-04-07 14:05:12 -04:00
Cobra ab34023c51 Fix set -e crash in image detection and device selection
ls glob on empty cache dir exits non-zero and kills script under
set -euo pipefail. Switched to find which exits 0 on no matches.
Same fix for grep|sed pipeline in device selection; added empty
DEVICE guard.
2026-04-07 14:02:32 -04:00
Cobra 0e49eb914e Add operator SD setup wizard: flash, configure, first-boot autonomy
Single script covers full drop implant prep: image download and flash,
WiFi (with UUID fix), per-device SSH keygen to Infisical, mode selection,
VPN (Tailscale/WireGuard), network alerter webhook, and first-boot service.
Insert card, power on, walk away.
2026-04-07 13:58:01 -04:00
Cobra 5e5f88d6cb Full autonomous first-boot: fix WiFi UUID, self-installing setup
WiFi keyfiles require UUID or NM silently ignores them — that was why
WiFi never connected. Rewrote preconfig_sd.sh to:
- Generate UUID for NM keyfile
- Copy BB source to /root/bb-src/ on the card
- Install bb-firstboot.service that runs setup.sh --enable-service
  after network-online.target, then disables itself
- Per-device keygen, private key to Infisical

Single command now produces a card that boots and self-installs.
2026-04-07 13:45:04 -04:00
Cobra e1f937f42c Generate per-device SSH keypair instead of copying operator keys
Each device gets a unique ed25519 keypair generated at preconfig time.
Private key goes to Infisical (bigbrother/SSH_PRIVKEY_<ID>), public key
to the SD card only. No operator keys or identifying comments on device.
2026-04-07 13:42:45 -04:00
Cobra 77aac72d31 Strip SSH key comments on deploy; add preconfig_sd.sh
Copying authorized_keys verbatim onto a drop implant leaks internal hostnames,
usernames, and tool names in key comments. preconfig_sd.sh now strips all
comments (awk '{print $1,$2}') when writing keys to SD card. deploy.sh adds
the same strip step on the live device as a safety net.
2026-04-07 13:41:44 -04:00
Cobra 8037462276 Randomize system hostname from device profile to match MAC identity 2026-04-07 13:33:54 -04:00
Cobra 7070f6548c Add reimage bootstrap: deploy.sh, setup_wifi.sh, fix setup.sh enable/reinstall, idempotent DB inserts 2026-04-07 13:20:15 -04:00
Cobra 0f754cfb7f Fix DB table/column mismatch and stale PID noise on startup
build_data.py created 'profiles' but mac_manager queries 'mac_profiles'.
Columns category/model renamed to device_type/device_name. device_type
values aligned with _CATEGORY_MAP in mac_manager (streaming, smart_tv,
phone, tablet, smart_speaker, iot, printer, gaming).

ja3_fingerprints.db table renamed from 'fingerprints' to 'ja3_profiles'
and expanded with all columns ja3_spoofer queries (name, description,
cipher_suites, extensions, elliptic_curves, ec_point_formats as JSON).

StateManager.reset_module_status() clears stale 'running' entries on
startup so watchdog doesn't flag old-session PIDs as dead modules.
Engine.start_all() calls reset before launch and does a 3s post-startup
liveness check, logging any modules that crashed immediately after fork.
2026-04-07 13:05:31 -04:00
Cobra e15e077be8 Skip MAC rotation on active WiFi interfaces to prevent ENETDOWN
When wlan0 is the primary data interface (WiFi-only deployment), changing
its MAC via SIOCSIFHWADDR drops the AP association and puts all AF_PACKET
sockets into ENETDOWN permanently until wpa_supplicant re-associates.

- _apply_profile: skip set_mac if _eth_iface is a WiFi interface
- _apply_profile: skip WiFi set_mac if _wifi_iface == _eth_iface (same card)
- stop: mirror the same skip logic for MAC restoration

DHCP hostname + TCP stack tuning still applied for blending on WiFi-only nodes.
2026-04-07 12:48:56 -04:00
Cobra 7f58f1cab3 Fix StateManager deadlock with explicit BEGIN IMMEDIATE + retry
with conn: context manager in Python sqlite3 doesn't respect busy_timeout
for the implicit BEGIN; under concurrent subprocess writes the transaction
would fail immediately. Replace with explicit BEGIN IMMEDIATE + retry loop
(6 attempts, 0.5s back-off) to handle WAL write contention.
2026-04-07 12:23:38 -04:00
Cobra a8b81f38c9 Fix credential_db schema conflict and add resilience
credential_sniffer and credential_db both wrote to the same credentials.db
with different schemas; credential_db's executescript failed when creating
the crack_status index on an existing table that lacked that column.

Fix: split credential_db's schema init into table DDL + migration + indexes
so missing columns are added before index creation runs. Migration also
handles any future schema drift.

state.py: add 30s timeout + busy_timeout PRAGMA to write connection so
concurrent subprocess writes stop failing with 'database is locked'.

capture_bus.py: reconnect on ENETDOWN instead of aborting the capture
loop — mac_manager temporarily brings the interface down during MAC
rotation which was silently killing all packet capture.
2026-04-07 12:19:56 -04:00
Cobra 1f0e3ee79a Cap stealth/intel/connectivity modules on Pi3B tier to prevent OOM
- Add max_stealth: 3 and max_other: 4 limits to pi3b tier in HARDWARE_TIERS
- Enforce those caps in _tier_allows() for stealth and intel+connectivity modules
- Disable heavy passive modules: vlan_discovery, network_mapper, auth_flow_tracker, smb_monitor, cloud_token_harvester, ldap_harvester, rdp_monitor, quic_analyzer
- Disable heavy stealth modules: lkm_rootkit, ids_tester, ja3_spoofer, overlayfs_manager, encrypted_storage, anti_forensics, traffic_mimicry
- Disable heavy intel modules: supply_chain_detect, security_posture, tool_output_parser, topology_mapper, user_timeline, net_intel
- Disable heavy connectivity modules: ble_emergency, cellular_backup, bridge, wireguard, wifi_client

On Pi 3B (1GB RAM, 700MB budget), this prevents 35+ subprocesses spawning and causing OOM crashes. Keeps lightweight modules running: dns_logger, tls_sni_extractor, credential_sniffer, host_discovery, os_fingerprint, traffic_analyzer, packet_capture, mac_manager, process_disguise, log_suppression, tmpfs_manager, watchdog, credential_db, change_detector, operator_audit, tailscale, data_exfil.
2026-04-06 22:44:52 -04:00
Cobra 7442dc24dd Fix CaptureBus cross-fork visibility — restart reader in each module subprocess
With multiprocessing fork, threads are not inherited. The parent's
CaptureBus reader thread runs in the parent but module subprocesses
subscribe AFTER fork, so their SubscriberQueue entries are added to
a child-local copy of _subscribers that the parent reader never sees.

Fix: reset and restart CaptureBus in each module subprocess so it
has its own reader thread on the inherited AF_PACKET socket. Each
module gets independent packet delivery. Linux AF_PACKET allows
multiple readers on the same interface.
2026-04-06 22:12:26 -04:00
Cobra 5be7fcf6d4 Fix module subprocess lifecycle and capture_bus injection bugs
Three bugs causing all modules to exit within seconds of startup:

1. _module_runner had no keep-alive loop after calling module.start().
   All modules use a thread-spawning pattern where start() returns
   immediately, so the subprocess exited and killed all daemon threads.
   Added while module._running: sleep(1) loop to block until stop().

2. Engine injected capture_bus under key 'capture_bus' but 9 modules
   (auth_flow_tracker, cloud_token_harvester, ldap_harvester, network_mapper,
   rdp_monitor, quic_analyzer, smb_monitor, db_interceptor, vlan_discovery)
   look for '_capture_bus'. Inject both keys so all modules get it.

3. mac_manager crashes on startup when innocuous_macs.db exists but has
   no mac_profiles table (DB not yet seeded). Added OperationalError
   handler to fall back to random OUI instead of crashing.
2026-04-06 21:57:30 -04:00
Cobra 78738622eb Securely wipe state.db on exit (#216)
- Add secure_wipe_file() to utils/crypto.py for file overwrites + deletion
- Add secure_wipe parameter to StateManager.stop() method
- Wipes all SQLite WAL files (.db, .db-wal, .db-shm) with 3 passes
- Normal exit now calls state.stop(secure_wipe=True) to clear state database
- Falls back to regular delete if secure wipe fails
- Prevents state.db from persisting on disk after shutdown
2026-04-06 11:44:44 -04:00
Cobra edf2ea7c36 Encrypt sensitive credential fields before event bus emission (#215)
- Add encrypt_credential_dict() and decrypt_credential_field() to utils/crypto.py
- Create utils/credential_encryption.py with encryption/decryption helpers
- Add get_credential_encryption_key() to retrieve key from Infisical at runtime
- Add emit_credential_found() wrapper for modules to use instead of direct bus.emit()
- Update all 15 modules emitting CREDENTIAL_FOUND to use encrypted wrapper
- Update 4 modules consuming CREDENTIAL_FOUND to decrypt payload before processing
- Sensitive fields (username, password, hash, token, etc.) encrypted with AES-256-GCM
- Falls back to plaintext if encryption key unavailable or encryption fails
2026-04-06 11:43:46 -04:00
Cobra f15b8994cd Fix #214: Prevent ToolManager crash callback deadlock
- Move crash_callback execution outside of self._lock
- Callback is called after releasing the monitor lock
- Re-acquire lock only for restart decision logic
- Prevents deadlock if callback tries to acquire same lock
- Maintains thread safety for restart and process state updates
2026-04-06 11:40:36 -04:00
Cobra 1b93378f02 Fix #213: Guard BIGBROTHER_DESIGN.md from deployment
- Add BIGBROTHER_DESIGN.md to .gitignore (prevent accidental commits)
- Remove from git tracking (already committed, but won't be in future releases)
- Design document contains sensitive operational details
- Prevents disclosure of architecture during implant extraction
2026-04-06 11:40:03 -04:00
Cobra 50deaf0cfb Fix #212: Remove autossh reverse tunnel module
- Delete modules/connectivity/reverse_tunnel.py (contradicts design)
- BigBrother design specifies WireGuard-only operator access
- Reverse SSH tunnel introduces unnecessary complexity and OPSEC risk
- Operator access is now exclusively through WireGuard VPN per spec
2026-04-06 11:39:56 -04:00
Cobra 1eb35c9050 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
2026-04-06 11:39:48 -04:00
Cobra ae4933044b Fix #209: Prevent SSH MITM in data_exfil.py exfiltration
- Replace StrictHostKeyChecking=no with accept-new (verify on first connect)
- Require ssh_known_hosts_file config key pointing to operator's known_hosts
- Validate known_hosts file exists before attempting transfer
- Fail explicitly if known_hosts not configured (prevents silent MITM vulnerability)
- Uses -o UserKnownHostsFile=path to use pinned host keys
2026-04-06 11:39:11 -04:00
Cobra e9735a15bb Fix #208: Prevent SSTI in responder_mgr.py Jinja2 template
- Use jinja2.Environment with BaseLoader instead of Template
- Enable autoescape=True to escape all template variables
- Sanitize relay_targets by converting to strings: [str(ip) for ip in ...]
- Prevents template injection even if relay_targets contains malicious content
2026-04-06 11:38:59 -04:00
Cobra 6ae10fd2f3 Fix #207: Prevent command injection in bettercap_api.py
- set_parameter() now validates param name with regex (alphanumeric, dots, underscores)
- set_parameter() quotes value with repr() to prevent argument injection
- load_caplet() validates path exists, is absolute, and ends with .cap/.caplet
- load_caplet() quotes caplet path for safe interpolation into bettercap command
2026-04-06 11:38:37 -04:00
Cobra 156144c1a7 Fix indentation issues in passive modules requires_capture_bus attribute
- Removed misplaced requires_capture_bus entries that broke indentation
- Added requires_capture_bus = True correctly after requires_root in all passive modules
- All passive modules now have valid Python syntax
2026-04-06 11:37:43 -04:00
Cobra 8dd053e337 Fix #204: Instantiate and inject CaptureBus in Engine
- Engine.__init__ now initializes self.capture_bus = None
- Engine.start_all() instantiates CaptureBus before starting modules
- CaptureBus uses resolved interface from config
- Inject capture_bus into configs of all modules with requires_capture_bus=True
- Engine.stop_all() properly stops CaptureBus after stopping modules
- CaptureBus instantiation includes error handling with fallback
2026-04-06 11:37:15 -04:00
Cobra 04eae3a43e Add requires_capture_bus attribute to BaseModule and passive modules
- BaseModule now has requires_capture_bus = False default
- All 17 passive modules set requires_capture_bus = True
- bigbrother.py imports CaptureBus from core.capture_bus
- Ready for Engine to instantiate and inject CaptureBus
2026-04-06 11:36:24 -04:00
Cobra 59cdda0596 Fix #206: Resolve auto interface to actual interface name
- Engine.__init__ now detects actual interface when config has 'auto'
- Uses get_primary_interface() to find default route interface
- PacketCapture module updated to use detected interface with fallback
- Handles Pi Zero 2W (wlan0) and other non-eth0 systems
2026-04-06 11:35:52 -04:00
Cobra 841d43a3b3 Document operator dispositions from post-review session
LUKS complexity deferred — operator uses disposable cloud VPS/Matrix infra
so on-device encryption provides diminishing returns. Captured device
exposes only target data + dead-end relay credentials.

autossh removal reclassified from detection risk to design violation —
persistent outbound tunnel contradicts passive/dormant architecture.

NOT-FIXING: Matrix homeserver default (opt-in only), creds in /dev/shm
(victim data by design), WireGuard key path (dead-end VPS mitigates).
2026-04-06 11:33:00 -04:00
Cobra eef574f0ca Fix duplicate IR-014 entry and deduplication error in consolidated report
Removed spurious second IR-014 (Verbose Module Startup Logging) which did not exist in any agent output.
This finding was causing confusion between the deployment blocker IR-014 (missing get_hardware_tier() import, CRITICAL)
and the false entry. Corrects triage table consistency and ensures all findings are grounded in actual agent analysis.
2026-04-06 09:51:09 -04:00
n0mad1k 054dc45cd5 Document comprehensive fix plan for daemon initialization failures 2026-04-06 09:15:40 -04:00
n0mad1k 516b7908a6 Add absent_count column and commented-out grace period threshold for tripwire resets 2026-04-06 08:52:30 -04:00
n0mad1k 0156101f11 Rewrite net_alerter with presence tracking: baseline on first run, alert on join and rejoin 2026-04-06 08:47:48 -04:00
n0mad1k 532f5f4a33 Fix net_alerter: don't treat 403 as token expiry — room permission errors were silently dropping all alerts 2026-04-06 08:27:42 -04:00
n0mad1k 75703d7ef6 Auto-refresh Matrix token on 401 instead of silently dropping alerts 2026-03-25 09:33:15 -04:00