Initial public release
Full BigBrother network implant - passive SOC + active exploitation. Personal identifiers removed; all capabilities intact. See README.md for setup and docs/deployment.md for detailed deployment.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Encrypted log writer for SystemMonitor. Named bb_logging to avoid shadowing stdlib logging."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
LOG_FORMAT = "[{timestamp}] [{module}] [{level}] {message}"
|
||||
MAX_LOG_SIZE = 10 * 1024 * 1024 # 10MB default rotation size
|
||||
LOG_DIR = "storage/logs"
|
||||
|
||||
|
||||
class EncryptedLogHandler(logging.Handler):
|
||||
def __init__(
|
||||
self,
|
||||
module_name: str,
|
||||
log_dir: str = LOG_DIR,
|
||||
max_bytes: int = MAX_LOG_SIZE,
|
||||
encrypt: bool = False,
|
||||
crypto_engine=None,
|
||||
):
|
||||
super().__init__()
|
||||
self.module_name = module_name
|
||||
self.log_dir = Path(log_dir)
|
||||
self.log_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.max_bytes = max_bytes
|
||||
self.encrypt = encrypt
|
||||
self.crypto_engine = crypto_engine
|
||||
self._log_path = self.log_dir / f"{module_name}.log"
|
||||
self._file = None
|
||||
self._current_size = 0
|
||||
self._open_file()
|
||||
|
||||
def _open_file(self):
|
||||
if self._file:
|
||||
self._file.close()
|
||||
mode = "ab" if self.encrypt else "a"
|
||||
self._file = open(self._log_path, mode)
|
||||
self._current_size = self._log_path.stat().st_size if self._log_path.exists() else 0
|
||||
|
||||
def _rotate(self):
|
||||
if self._file:
|
||||
self._file.close()
|
||||
rotated = self._log_path.with_suffix(f".log.{int(time.time())}")
|
||||
if self._log_path.exists():
|
||||
self._log_path.rename(rotated)
|
||||
self._open_file()
|
||||
|
||||
def emit(self, record):
|
||||
try:
|
||||
ts = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(record.created))
|
||||
line = LOG_FORMAT.format(
|
||||
timestamp=ts,
|
||||
module=self.module_name,
|
||||
level=record.levelname,
|
||||
message=record.getMessage(),
|
||||
)
|
||||
if self.encrypt and self.crypto_engine:
|
||||
data = self.crypto_engine.encrypt(line.encode("utf-8"))
|
||||
length_prefix = len(data).to_bytes(4, "big")
|
||||
self._file.write(length_prefix)
|
||||
self._file.write(data)
|
||||
self._current_size += 4 + len(data)
|
||||
else:
|
||||
line += "\n"
|
||||
self._file.write(line)
|
||||
self._current_size += len(line.encode("utf-8"))
|
||||
|
||||
self._file.flush()
|
||||
|
||||
if self._current_size >= self.max_bytes:
|
||||
self._rotate()
|
||||
except Exception:
|
||||
self.handleError(record)
|
||||
|
||||
def close(self):
|
||||
if self._file:
|
||||
self._file.close()
|
||||
self._file = None
|
||||
super().close()
|
||||
|
||||
|
||||
class BBLogger:
|
||||
def __init__(
|
||||
self,
|
||||
module_name: str,
|
||||
log_dir: str = LOG_DIR,
|
||||
max_bytes: int = MAX_LOG_SIZE,
|
||||
level: int = logging.INFO,
|
||||
encrypt: bool = False,
|
||||
crypto_engine=None,
|
||||
suppress_stdout: bool = True,
|
||||
):
|
||||
self.module_name = module_name
|
||||
self.logger = logging.getLogger(f"sensor.{module_name}")
|
||||
self.logger.setLevel(level)
|
||||
self.logger.propagate = False
|
||||
|
||||
# Clear existing handlers to prevent duplicates
|
||||
self.logger.handlers.clear()
|
||||
|
||||
self._file_handler = EncryptedLogHandler(
|
||||
module_name=module_name,
|
||||
log_dir=log_dir,
|
||||
max_bytes=max_bytes,
|
||||
encrypt=encrypt,
|
||||
crypto_engine=crypto_engine,
|
||||
)
|
||||
self._file_handler.setLevel(level)
|
||||
self.logger.addHandler(self._file_handler)
|
||||
|
||||
if not suppress_stdout:
|
||||
console = logging.StreamHandler()
|
||||
console.setLevel(level)
|
||||
fmt = logging.Formatter(
|
||||
"[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
console.setFormatter(fmt)
|
||||
self.logger.addHandler(console)
|
||||
|
||||
def debug(self, msg: str, *args, **kwargs):
|
||||
self.logger.debug(msg, *args, **kwargs)
|
||||
|
||||
def info(self, msg: str, *args, **kwargs):
|
||||
self.logger.info(msg, *args, **kwargs)
|
||||
|
||||
def warning(self, msg: str, *args, **kwargs):
|
||||
self.logger.warning(msg, *args, **kwargs)
|
||||
|
||||
def error(self, msg: str, *args, **kwargs):
|
||||
self.logger.error(msg, *args, **kwargs)
|
||||
|
||||
def critical(self, msg: str, *args, **kwargs):
|
||||
self.logger.critical(msg, *args, **kwargs)
|
||||
|
||||
def set_level(self, level: int):
|
||||
self.logger.setLevel(level)
|
||||
self._file_handler.setLevel(level)
|
||||
|
||||
def close(self):
|
||||
self._file_handler.close()
|
||||
self.logger.removeHandler(self._file_handler)
|
||||
Reference in New Issue
Block a user