FiniteStateRedAgent
Bases: BaseAgent
A red agent that performs as a finite state automata, transitioning the hosts it is aware of between different states of knowledge.
Throughout the episode, the hosts will transition between the 8 different states. This will mainly occur via the state transition matrices, depending on action success or failure. However, other external factors may affect the state, such as Blue removing a session from a host or the host being outside the agent's area of influence (their assigned subnets).
Functions
__init__
Initialises the FSM red agent.
Creates the variables to store internal knowledge for the agent. Sets the state transitions (basic) and host priorities (none), for the agent.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str
|
agent name |
None
|
np_random |
Tuple[np.random.Generator, Any]
|
numpy random number generator |
None
|
agent_subnets |
List[IPv4Subnet]
|
list of subnet cidr bounds that this red agent can reach |
None
|
action_list
The possible actions that can be performed by the agent, in the order of the columns of the state transition matrices.
Returns:
Name | Type | Description |
---|---|---|
actions |
List[Action]
|
List of the 9 actions that a red agent can perform in CC4 |
get_action
The choosing and returning of the action to be used for the current step.
In order to make an appropriate choice, the observations from the previous action must be processed. This is carried out through private functions, in the order listed below:
_host_state_transition(action, success)
- The host that was last acted on has its state changed based on the action success.
_process_new_observations(observation)
- The details of the observation is then processed for newly discovered hosts and decoy discoveries.
_session_removal_state_change(observation)
- The sessions are then checked to make sure none were lost in the last step, and changing their host states accordingly.
An textual output is available if the print attributes are set to True (function last_turn_summary
).
The next action for the current step is then selected:
- If the previous action is still 'in progress' then Sleep is returned, as this action will not be used.
_choose_host_and_action(action_space, known_hosts)
- A host is chosen; either randomly or based on host state priority.
- An action on that host is then selected according to the
state_transition_probabilities
matrix.
- If the action chosen is
ExploitRemoteService_cc4
, then the selector that takes into account the detected decoys is chosen. - The action is stored for reference and returned.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
observation |
dict
|
The dictionary holding the observations made by the agent from the previous action |
required |
action_space |
dict
|
The restricted space that the agent knows about and can act on, given by the environment. |
required |
last_turn_summary
Prints action name, parameters, success and sometimes observation and host states.
If self.print_action_output
is True, the function will run and the observed action and its success will be outputted to the terminal.
If self.print_obs_output
is True, additionally the observation and internal host_states
dictionaries will be outputted. This should only be True for debugging.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
observation |
dict
|
the observation that the agent just received about its previous action |
required |
action |
str
|
the previous action that was taken |
required |
success |
Union[bool, CyEnums.TrinaryEnum]
|
the success of the previous action |
required |
set_host_state_priority_list
Abstract function for child classes to overwrite with a host state priority list.
Each dictionary value must be an integer or float from 0 to 100, with the total sum of values equaling 100.
Example
Returns:
Name | Type | Description |
---|---|---|
host_state_priority_list |
None
|
when used in variant child classes, a dict would be returned. |
set_initial_values
The action parameter values in the action space are sanitised for internal use.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
action_space |
dict
|
|
required |
observation |
dict
|
|
required |
state_transitions_failure
The state transition matrix for an unsuccessful action on a host.
There is a row for each of the host states: K, KD, S, SD, U, UD, R, RD.
Then there is a column for each of the actions, in the order of the action_list
.
All column 0 must have transition state as all hosts in subnet are transitioned
Example
map = {
'K' : ['K' , 'K' , 'K' , None, None, None, None, None, None],
'KD' : ['KD', 'KD', 'KD', None, None, None, None, None, None],
'S' : ['S' , None, None, 'S' , 'S' , None, None, None, None],
'SD' : ['SD', None, None, 'SD', 'SD', None, None, None, None],
'U' : ['U' , None, None, None, None, 'U' , None, None, 'U' ],
'UD' : ['UD', None, None, None, None, 'UD', None, None, 'UD'],
'R' : ['R' , None, None, None, None, None, 'R' , 'R' , 'R' ],
'RD' : ['RD', None, None, None, None, None, 'RD', 'RD', 'RD'],
'F' : ['F', None, None, None, None, None, None, None, None],
}
Returns:
Name | Type | Description |
---|---|---|
map |
Dict[str, List[float]]
|
|
state_transitions_probability
Returns a state transitions probability matrix.
There is a row for each of the host states: K, KD, S, SD, U, UD, R, RD.
Then there is a column for each of the actions, in the order of the action_list
.
Example
map = {
'K' : [0.5, 0.25, 0.25, None, None, None, None, None, None],
'KD' : [None, 0.5, 0.5, None, None, None, None, None, None],
'S' : [0.25, None, None, 0.25, 0.5 , None, None, None, None],
'SD' : [None, None, None, 0.25, 0.75, None, None, None, None],
'U' : [0.5 , None, None, None, None, 0.5 , None, None, 0.0 ],
'UD' : [None, None, None, None, None, 1.0 , None, None, 0.0 ],
'R' : [0.5, None, None, None, None, None, 0.25, 0.25, 0.0 ],
'RD' : [None, None, None, None, None, None, 0.5, 0.5, 0.0 ],
}
Returns:
Name | Type | Description |
---|---|---|
matrix |
Dict[str, List[float]]
|
|
state_transitions_success
The state transition matrix for a successful action on a host.
There is a row for each of the host states: K, KD, S, SD, U, UD, R, RD.
Then there is a column for each of the actions, in the order of the action_list
.
All column 0 must have transition state as all hosts in subnet are transitioned
Example
map = {
'K' : ['KD', 'S', 'S', None, None, None, None, None, None],
'KD' : ['KD', 'SD', 'SD', None, None, None, None, None, None],
'S' : ['SD', None, None, 'S' , 'U' , None, None, None, None],
'SD' : ['SD', None, None, 'SD', 'UD', None, None, None, None],
'U' : ['UD', None, None, None, None, 'R' , None, None, 'S' ],
'UD' : ['UD', None, None, None, None, 'RD', None, None, 'SD'],
'R' : ['RD', None, None, None, None, None, 'R' , 'R' , 'S' ],
'RD' : ['RD', None, None, None, None, None, 'RD', 'RD', 'SD'],
'F' : ['F', None, None, None, None, None, None, None, None],
}
Returns:
Name | Type | Description |
---|---|---|
map |
Dict[str, List[float]]
|
|