Skip to content

Global Defender

Note

The global defender, available in previous environment versions, will not be supported in the future. To enable backward compatibility, the global defender functionality can be enabled by adding use_global_defender: True to the configuration YAML file in the env section. This option is disabled by default.

The global defender is a stochastic (non-agentic) detection system that simulates a SIEM. It monitors agent actions and probabilistically detects suspicious behavior patterns.

How Detection Works

All actions are analyzed in time windows (TW) of 5 actions (by default). Every new action slides the window by one position. The defender evaluates whether the latest action should trigger a detection based on three types of thresholds.

Detection Thresholds

Detection Probabilities

Each action type has a base probability of being detected. However, detection only triggers if additional behavioral patterns are met (see below).

Action Type Detection Probability
ScanNetwork 0.05
FindServices 0.075
ExploitService 0.1
FindData 0.025
ExfiltrateData 0.025
BlockIP 0.01

For example, a single ScanNetwork action has a 5% probability of being detected.

Type Ratio Threshold

Defines how frequently an action must appear in the time window to be considered for detection. If the ratio is below the threshold, no detection occurs.

Example: If the last action is ScanNetwork in a TW of [ScanNetwork, FindService, ScanNetwork, FindData, ScanNetwork], the ratio is 3/5 = 0.6.

Action Type Ratio Threshold
ScanNetwork 0.25
FindServices 0.3
ExploitService 0.25
FindData 0.5
ExfiltrateData 0.25
BlockIP 1

Consecutive Actions Threshold

Determines the maximum number of consecutive occurrences of an action type within the time window before detection is triggered.

Action Type Consecutive Threshold
ScanNetwork 2
FindServices 3
ExfiltrateData 2

Repeated Action Threshold

Applies to certain action types and defines the number of times a specific action must appear in the entire episode before it can be considered for detection.

Action Type Repeated Threshold
ExploitService 2
FindData 2

Decision Logic

The system monitors actions and maintains a history of recent ones within the time window:

  1. If an action's Type Ratio Threshold is met within the time window or it exceeds the Consecutive Actions Threshold, it is evaluated for detection.
  2. If the action type has a Repeated Action Threshold and has not been repeated enough times in the episode, it is ignored.
  3. If an action meets the conditions above, it is subject to detection based on its predefined Detection Probability.
  4. Actions that do not meet any threshold conditions are ignored, ensuring that occasional activity does not lead to unnecessary detections.

This approach ensures that only repeated or excessive behavior is flagged, reducing false positives while maintaining a realistic monitoring system.

API Reference

netsecgame.game.global_defender

GlobalDefender

Source code in netsecgame/game/global_defender.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(self):

    # The probability of detecting an action is defined by the following dictionary
    self._DEFAULT_DETECTION_PROBS = {
        ActionType.ScanNetwork: 0.05,
        ActionType.FindServices: 0.075,
        ActionType.ExploitService: 0.1,
        ActionType.FindData: 0.025,
        ActionType.ExfiltrateData: 0.025,
        ActionType.BlockIP: 0.01
    }


    # Ratios of action types in the time window (TW) for each action type. The ratio should be higher than the defined value to trigger a detection check
    self._TW_TYPE_RATIOS_THRESHOLD = {
        ActionType.ScanNetwork: 0.25,
        ActionType.FindServices: 0.3,
        ActionType.ExploitService: 0.25,
        ActionType.FindData: 0.5,
        ActionType.ExfiltrateData: 0.25,
        ActionType.BlockIP: 1
    }

    # Thresholds for consecutive actions of the same type in the TW. Only if the threshold is crossed, the detection check is triggered
    self._TW_CONSECUTIVE_TYPE_THRESHOLD = {
        ActionType.ScanNetwork: 2,
        ActionType.FindServices: 3,
        ActionType.ExfiltrateData: 2
    }

    # Thresholds for repeated actions in the episode. Only if the threshold is crossed, the detection check is triggered
    self._EPISODE_REPEATED_ACTION_THRESHOLD = {
        ActionType.ExploitService: 2,
        ActionType.FindData: 2,
    }

stochastic

Performs a simple random detection based on predefined probability for an ActionType.

Parameters:

Name Type Description Default
action_type ActionType

The type of action to check for detection.

required

Returns:

Name Type Description
bool bool

True if detected, False otherwise.

Source code in netsecgame/game/global_defender.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def stochastic(self, action_type: ActionType) -> bool:
    """
    Performs a simple random detection based on predefined probability for an ActionType.

    Args:
        action_type (ActionType): The type of action to check for detection.

    Returns:
        bool: True if detected, False otherwise.
    """
    roll = random()
    if roll < self._DEFAULT_DETECTION_PROBS[action_type]:
        return True
    else:
        return False

stochastic_with_threshold

Determines detection based on set probabilities, but only if pre-defined thresholds are crossed.

Parameters:

Name Type Description Default
action Action

The current action being performed.

required
episode_actions List[Dict[str, Any]]

The history of actions in the current episode.

required
tw_size int

The size of the time window to consider for thresholds. Defaults to 5.

5

Returns:

Name Type Description
bool bool

True if the action is detected, False otherwise.

Source code in netsecgame/game/global_defender.py
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def stochastic_with_threshold(self, action: Action, episode_actions: List[Dict[str, Any]], tw_size: int = 5) -> bool:
    """
    Determines detection based on set probabilities, but only if pre-defined thresholds are crossed.

    Args:
        action (Action): The current action being performed.
        episode_actions (List[Dict[str, Any]]): The history of actions in the current episode.
        tw_size (int): The size of the time window to consider for thresholds. Defaults to 5.

    Returns:
        bool: True if the action is detected, False otherwise.
    """
    # extend the episode with the latest action
    # We need to copy the list before the copying, so we avoid modifying it when it is returned. Modifycation of passed list is the default behavior in Python
    temp_episode_actions = episode_actions.copy()
    temp_episode_actions.append(action.as_dict)
    if len(temp_episode_actions) >= tw_size:
        last_n_actions = temp_episode_actions[-tw_size:]
        last_n_action_types = [action['action_type'] for action in last_n_actions]
        # compute ratio of action type in the TW
        tw_ratio = last_n_action_types.count(str(action.type))/tw_size
        # Count how many times this exact (parametrized) action was played in episode
        repeats_in_episode = temp_episode_actions.count(action.as_dict)
        # compute the highest consecutive number of action type in TW
        max_consecutive_action_type = max(sum(1 for item in grouped if item == str(action.type))
                                            for _, grouped in groupby(last_n_action_types))

        if action.type in self._TW_CONSECUTIVE_TYPE_THRESHOLD.keys():
            # ScanNetwork, FindServices, ExfiltrateData
            if tw_ratio < self._TW_TYPE_RATIOS_THRESHOLD[action.type] and max_consecutive_action_type < self._TW_CONSECUTIVE_TYPE_THRESHOLD[action.type]:
                return False
            else:
                return self.stochastic(action.type)
        elif action.type in self._EPISODE_REPEATED_ACTION_THRESHOLD.keys():
            # FindData, Exploit service
            if tw_ratio < self._TW_TYPE_RATIOS_THRESHOLD[action.type] and repeats_in_episode < self._EPISODE_REPEATED_ACTION_THRESHOLD[action.type]:
                return False
            else:
                return self.stochastic(action.type)
        else: #Other actions - Do not detect
            return False
    else:
        return False