Source code for detector.plugins.domainator_detector

from src.detector.detector import DetectorBase
import numpy as np
from collections import defaultdict
import itertools
import pylcs
import Levenshtein

from src.base.log_config import get_logger
from src.detector.plugins.domainator_utils import (
    strip_domain,
    get_domainator_features,
)

module_name = "data_analysis.detector"
logger = get_logger(module_name)


[docs] class DomainatorDetector(DetectorBase): """ Detector implementation for identifying data exfiltration and command and control on the subdomain level. This class extends the DetectorBase to provide specific functionality for detecting malicious queries. It analyzes subdomain similarity characteristics based on grouping of the queries in windows of fixed size, in order to identify potential data exfiltration or command and control. The detector extracts various statistical similarity features from windows of subdomains to make predictions about whether a query is likely malicious. """
[docs] def __init__( self, detector_config, consume_topic, produce_topics=None, downstream_detector_topics=None, ): """ Initialize the Domainator detector with configuration parameters. Sets up the detector with the model base URL and passes configuration to the base class for standard detector initialization. Args: detector_config (dict): Configuration dictionary containing detector-specific parameters including base_url, model, checksum, and threshold. consume_topic (str): Kafka topic from which the detector will consume messages. """ self.model_base_url = detector_config["base_url"] self.message_queues = defaultdict(list) super().__init__( detector_config, consume_topic, produce_topics, downstream_detector_topics )
[docs] def predict(self, messages): """ Process a window of messages and predict if the domain is likely to be used for malicious exfiltration and communication. Extracts features from the subdomains in the messages and uses the loaded machine learning model to generate prediction probabilities. Args: message (list): A list containing the messages data, expected to have a "domain_name" key with the domain to analyze. Returns: np.ndarray: Prediction probabilities for each class. Typically a 2D array where the shape is (1, 2) for binary classification (benign/malicious). """ queries = [message["domain_name"] for message in messages] y_pred = self.model.predict_proba(get_domainator_features(queries)) return y_pred
[docs] def detect(self): logger.info("Start detecting malicious requests.") for message in self.messages: message_domain = strip_domain(message["domain_name"]) self.message_queues[message_domain].append(message) if len(self.message_queues[message_domain]) >= 3: y_pred = self.predict(self.message_queues[message_domain]) logger.info(f"Prediction: {y_pred}") if np.argmax(y_pred, axis=1) == 1 and y_pred[0][1] > self.threshold: logger.info("Append malicious request domain to warning.") warning = { "request": self.message_queues[message_domain], "probability": float(y_pred[0][1]), "name": self.name, "sha256": self.checksum, } self.warnings.append(warning) if len(self.message_queues[message_domain]) >= 10: del self.message_queues[message_domain][0]