Actions

Action related classes for the NASim environment.

This module contains the different action classes that are used to implement actions within a NASim environment, along within the different ActionSpace classes, and the ActionResult class.

Notes

Actions:

Every action inherits from the base Action class, which defines some common attributes and functions. Different types of actions are implemented as subclasses of the Action class.

Action types implemented:

Action Spaces:

There are two types of action spaces, depending on if you are using flat actions or not:

class nasim.envs.action.Action(name, target, cost, prob=1.0, req_access=USER, **kwargs)

The base abstract action class in the environment

There are multiple types of actions (e.g. exploit, scan, etc.), but every action has some common attributes.

name

the name of action

Type:str
target

the (subnet, host) address of target of the action. The target of the action could be the address of a host that the action is being used against (e.g. for exploits or targeted scans) or could be the host that the action is being executed on (e.g. for subnet scans).

Type:(int, int)
cost

the cost of performing the action

Type:float
prob

the success probability of the action. This is the probability that the action works given that it’s preconditions are met. E.g. a remote exploit targeting a host that you cannot communicate with will always fail. For deterministic actions this will be 1.0.

Type:float
req_access

the required access level to perform action. For for on host actions (i.e. subnet scan, process scan, and privilege escalation) this will be the access on the target. For remote actions (i.e. service scan, os scan, and exploits) this will be the access on a pivot host (i.e. a compromised host that can reach the target).

Type:AccessLevel,
__init__(name, target, cost, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • name (str) – name of action
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
is_exploit()

Check if action is an exploit

Returns:True if action is exploit, otherwise False
Return type:bool
is_noop()

Check if action is a do nothing action.

Returns:True if action is a noop action, otherwise False
Return type:bool
is_os_scan()

Check if action is an OS scan

Returns:True if action is an OS scan, otherwise False
Return type:bool
is_privilege_escalation()

Check if action is privilege escalation action

Returns:True if action is privilege escalation action, otherwise False
Return type:bool
is_process_scan()

Check if action is a process scan

Returns:True if action is a process scan, otherwise False
Return type:bool
is_remote()

Check if action is a remote action

A remote action is one where the target host is a remote host (i.e. the action is not performed locally on the target)

Returns:True if action is remote, otherwise False
Return type:bool
is_scan()

Check if action is a scan

Returns:True if action is scan, otherwise False
Return type:bool
is_service_scan()

Check if action is a service scan

Returns:True if action is service scan, otherwise False
Return type:bool
is_subnet_scan()

Check if action is a subnet scan

Returns:True if action is a subnet scan, otherwise False
Return type:bool
class nasim.envs.action.ActionResult(success, value=0.0, services=None, os=None, processes=None, access=None, discovered=None, connection_error=False, permission_error=False, undefined_error=False, newly_discovered=None)

A dataclass for storing the results of an Action.

These results are then used to update the full state and observation.

success

True if exploit/scan was successful, False otherwise

Type:bool
value

value gained from action. Is the value of the host if successfuly exploited, otherwise 0

Type:float
services

services identified by action.

Type:dict
os

OS identified by action

Type:dict
processes

processes identified by action

Type:dict
access

access gained by action

Type:dict
discovered

host addresses discovered by action

Type:dict
connection_error

True if action failed due to connection error (e.g. could not reach target)

Type:bool
permission_error

True if action failed due to a permission error (e.g. incorrect access level to perform action)

Type:bool
undefined_error

True if action failed due to an undefined error (e.g. random exploit failure)

Type:bool
newly_discovered

host addresses discovered for the first time by action

Type:dict
__init__(success, value=0.0, services=None, os=None, processes=None, access=None, discovered=None, connection_error=False, permission_error=False, undefined_error=False, newly_discovered=None)
Parameters:
  • success (bool) – True if exploit/scan was successful, False otherwise
  • value (float, optional) – value gained from action (default=0.0)
  • services (dict, optional) – services identified by action (default=None={})
  • os (dict, optional) – OS identified by action (default=None={})
  • processes (dict, optional) – processes identified by action (default=None={})
  • access (dict, optional) – access gained by action (default=None={})
  • discovered (dict, optional) – host addresses discovered by action (default=None={})
  • connection_error (bool, optional) – True if action failed due to connection error (default=False)
  • permission_error (bool, optional) – True if action failed due to a permission error (default=False)
  • undefined_error (bool, optional) – True if action failed due to an undefined error (default=False)
  • newly_discovered (dict, optional) – host addresses discovered for first time by action (default=None)
info()

Get results as dict

Returns:action results information
Return type:dict
class nasim.envs.action.Exploit(name, target, cost, service, os=None, access=0, prob=1.0, req_access=USER, **kwargs)

An Exploit action in the environment

Inherits from the base Action Class.

service

the service targeted by exploit

Type:str
os

the OS targeted by exploit. If None then exploit works for all OSs.

Type:str
access

the access level gained on target if exploit succeeds.

Type:int
__init__(name, target, cost, service, os=None, access=0, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • service (str) – the target service
  • os (str, optional) – the target OS of exploit, if None then exploit works for all OS (default=None)
  • access (int, optional) – the access level gained on target if exploit succeeds (default=0)
  • prob (float, optional) – probability of success (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.FlatActionSpace(scenario)

Flat Action space for NASim environment.

Inherits and implements the gym.spaces.Discrete action space

n

the number of actions in the action space

Type:int
actions

the list of the Actions in the action space

Type:list of Actions
__init__(scenario)
Parameters:scenario (Scenario) – scenario description
get_action(action_idx)

Get Action object corresponding to action idx

Parameters:action_idx (int) – the action idx
Returns:Corresponding Action object
Return type:Action
class nasim.envs.action.NoOp(*args, **kwargs)

A do nothing action in the environment

Inherits from the base Action Class

__init__(*args, **kwargs)
Parameters:
  • name (str) – name of action
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.OSScan(target, cost, prob=1.0, req_access=USER, **kwargs)

An OS Scan action in the environment

Inherits from the base Action Class.

__init__(target, cost, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.ParameterisedActionSpace(scenario)

A parameterised action space for NASim environment.

Inherits and implements the gym.spaces.MultiDiscrete action space, where each dimension corresponds to a different action parameter.

The action parameters (in order) are:

  1. Action Type = [0, 5]

    Where:

    0=Exploit,

    1=PrivilegeEscalation,

    2=ServiceScan,

    3=OSScan,

    4=SubnetScan,

    5=ProcessScan,

  2. Subnet = [0, #subnets-1]

    -1 since we don’t include the internet subnet

  3. Host = [0, max subnets size-1]

  4. OS = [0, #OS]

    Where 0=None.

  5. Service = [0, #services - 1]

  6. Process = [0, #processes]

    Where 0=None.

Note that OS, Service and Process are only important for exploits and privilege escalation actions.

nvec

vector of the of the size of each parameter

Type:Numpy.Array
actions

the list of all the Actions in the action space

Type:list of Actions
__init__(scenario)
Parameters:scenario (Scenario) – scenario description
get_action(action_vec)

Get Action object corresponding to action vector.

Parameters:action_vector (list of ints or tuple of ints or Numpy.Array) – the action vector
Returns:Corresponding Action object
Return type:Action

Notes

  1. if host# specified in action vector is greater than the number of hosts in the specified subnet, then host# will be changed to host# % subnet size.
  2. if action is an exploit and parameters do not match any exploit definition in the scenario description then a NoOp action is returned with 0 cost.
class nasim.envs.action.PrivilegeEscalation(name, target, cost, access, process=None, os=None, prob=1.0, req_access=USER, **kwargs)

A privilege escalation action in the environment

Inherits from the base Action Class.

process

the process targeted by the privilege escalation. If None the action works independent of a process

Type:str
os

the OS targeted by privilege escalation. If None then action works for all OSs.

Type:str
access

the access level resulting from privilege escalation action

Type:int
__init__(name, target, cost, access, process=None, os=None, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • access (int) – the access level resulting from the privilege escalation
  • process (str, optional) – the target process, if None the action does not require a process to work (default=None)
  • os (str, optional) – the target OS of privilege escalation action, if None then action works for all OS (default=None)
  • prob (float, optional) – probability of success (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.ProcessScan(target, cost, prob=1.0, req_access=USER, **kwargs)

A Process Scan action in the environment

Inherits from the base Action Class.

__init__(target, cost, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.ServiceScan(target, cost, prob=1.0, req_access=USER, **kwargs)

A Service Scan action in the environment

Inherits from the base Action Class.

__init__(target, cost, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
class nasim.envs.action.SubnetScan(target, cost, prob=1.0, req_access=USER, **kwargs)

A Subnet Scan action in the environment

Inherits from the base Action Class.

__init__(target, cost, prob=1.0, req_access=USER, **kwargs)
Parameters:
  • target ((int, int)) – address of target
  • cost (float) – cost of performing action
  • prob (float, optional) – probability of success for a given action (default=1.0)
  • req_access (AccessLevel, optional) – the required access level to perform action (default=AccessLevel.USER)
nasim.envs.action.load_action_list(scenario)

Load list of actions for environment for given scenario

Parameters:scenario (Scenario) – the scenario
Returns:list of all actions in environment
Return type:list