Skip to content

WhiteBoxNetSecGame

Whitebox version of NSG is an extension of the NetSecGame which provides full action space for the agents upon registration in the game. This version is used for training of agents that require fixed size action space.

netsecgame.game.worlds.WhiteBoxNetSecGame.WhiteBoxNetSecGame

Bases: NetSecGame

WhiteBoxNetSecGame is an extension for the NetSecGame environment that provides list of all possible actions to each agent that registers in the game.

Initializes the WhiteBoxNetSecGame.

Parameters:

Name Type Description Default
game_host str

The host for the game server.

required
game_port int

The port for the game server.

required
task_config str

Path to the task configuration file.

required
seed Optional[int]

Random seed.

None
include_block_action bool

Whether to include BlockIP actions.

True
Source code in netsecgame/game/worlds/WhiteBoxNetSecGame.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def __init__(self, game_host: str, game_port: int, task_config: str, seed: Optional[int] = None, include_block_action: bool = True):
    """
    Initializes the WhiteBoxNetSecGame.

    Args:
        game_host (str): The host for the game server.
        game_port (int): The port for the game server.
        task_config (str): Path to the task configuration file.
        seed (Optional[int]): Random seed.
        include_block_action (bool): Whether to include BlockIP actions.
    """
    super().__init__(game_host, game_port, task_config, seed)
    self._all_actions = None
    self._include_block_action = include_block_action

_create_state_from_view

Creates a GameState from a view.

Parameters:

Name Type Description Default
view Dict[str, Any]

The view dictionary.

required
add_neighboring_nets bool

Whether to add neighboring networks.

True

Returns:

Name Type Description
GameState GameState

The generated game state.

Source code in netsecgame/game/worlds/WhiteBoxNetSecGame.py
145
146
147
148
149
150
151
152
153
154
155
156
def _create_state_from_view(self, view: Dict[str, Any], add_neighboring_nets: bool = True) -> GameState:
    """
    Creates a GameState from a view.

    Args:
        view (Dict[str, Any]): The view dictionary.
        add_neighboring_nets (bool): Whether to add neighboring networks.

    Returns:
        GameState: The generated game state.
    """
    return super()._create_state_from_view(view, add_neighboring_nets=add_neighboring_nets)

_dynamic_ip_change

Dynamic IP change is not supported for WhiteBoxNetSecGame.

Parameters:

Name Type Description Default
max_attempts int

Maximum number of attempts.

10

Returns:

Type Description
None

None

Source code in netsecgame/game/worlds/WhiteBoxNetSecGame.py
158
159
160
161
162
163
164
165
166
167
168
169
170
def _dynamic_ip_change(self, max_attempts: int = 10, seed=None) -> None:
    """
    Dynamic IP change is not supported for WhiteBoxNetSecGame.

    Args:
        max_attempts (int): Maximum number of attempts.

    Returns:
        None
    """
    warnings.warn("Dynamic IP change is not supported for WhiteBoxNetSecGame.", UserWarning)
    self.logger.warning("Dynamic IP change is not supported for WhiteBoxNetSecGame.")
    return None

_generate_all_actions

Generates a list of all possible actions for the game.

Returns:

Type Description
List[Action]

List[Action]: List of all possible actions.

Source code in netsecgame/game/worlds/WhiteBoxNetSecGame.py
 52
 53
 54
 55
 56
 57
 58
 59
 60
 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def _generate_all_actions(self)-> List[Action]:
    """
    Generates a list of all possible actions for the game.

    Returns:
        List[Action]: List of all possible actions.
    """
    actions = []
    all_ips = [self._ip_mapping[ip] for ip in self._ip_to_hostname.keys()]
    all_networks = self._networks.keys()
    all_data = set()
    ip_with_services = {}
    for ip in all_ips:
        if ip in self._ip_to_hostname:
            hostname = self._ip_to_hostname[ip]
            if hostname in self._services:
                ip_with_services[ip] = self._services[hostname]

    # Collect all data from all hosts
    for data in self._data.values():
        all_data.update(data)

    # sort all components to have a consistent order
    all_ips = sorted(list(all_ips))
    all_networks = sorted(list(all_networks))
    all_data = sorted(list(all_data))

    # Network Scans
    for source_host, target_network in itertools.product(all_ips, all_networks):
            actions.append(Action(
                ActionType.ScanNetwork,
                parameters={
                    "source_host": source_host,
                    "target_network": target_network
                }
            ))

    # Service Scans
    for source_host, target_host in itertools.product(all_ips, all_ips):
        actions.append(Action(
            ActionType.FindServices,
            parameters={
                "source_host": source_host,
                "target_host": target_host
            }
        ))
    # Service Exploits
    for source_host, target_host in itertools.product(all_ips, sorted(ip_with_services.keys())):
        for service in ip_with_services[target_host]:
            actions.append(Action(
                ActionType.ExploitService,
                parameters={
                    "source_host": source_host,
                    "target_host": target_host,
                    "target_service": service
                }
            ))
    # Data Scans
    for source_host, target_host in itertools.product(all_ips, all_ips):
        actions.append(Action(
            ActionType.FindData,
            parameters={
                "source_host": source_host,
                "target_host": target_host
            }
        ))
    # Data transfers
    for (source_host, target_host), datum in itertools.product(itertools.product(all_ips, all_ips), all_data):
        actions.append(Action(
            ActionType.ExfiltrateData,
            parameters={
                "source_host": source_host,
                "target_host": target_host,
                "data": datum
            }
        ))
    # Blocks
    if self._include_block_action:
        for (source_host, target_host), blocked_ip in itertools.product(itertools.product(all_ips, all_ips), all_ips):
            actions.append(Action(
                ActionType.BlockIP,
                parameters={
                    "source_host": source_host,
                    "target_host": target_host,
                    "blocked_ip": blocked_ip
                }
            ))
    self.logger.info(f"Created action mapping with {len(actions)} actions.")
    for action in actions:
        self.logger.debug(action)
    return actions

_initialize

Initializes the game state and generates all possible actions.

Returns:

Type Description
None

None

Source code in netsecgame/game/worlds/WhiteBoxNetSecGame.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def _initialize(self) -> None:
    """
    Initializes the game state and generates all possible actions.

    Returns:
        None
    """
    # First do the parent initialization
    super()._initialize()
    # All components are initialized, now we can set the action mapping
    self.logger.debug("Creating action mapping for the game.")
    self._all_actions = self._generate_all_actions()
    self._registration_info = {
        "all_actions": json.dumps([v.as_dict for v in self._all_actions]),
    } if self._all_actions is not None else {}