cyst.api.environment.environment
- class cyst.api.environment.environment.Environment
Bases:
ABCThe Environment provides a highest-level interface to controlling the simulation. It consists of a number of lower-level interfaces that provide a specific functionality.
- abstract property configuration: EnvironmentConfiguration
This interface is a collection of configuration interfaces for the environment, that are split according to their general functionality.
- Return type:
- abstract property control: EnvironmentControl
This interface provides mechanisms to control the execution of actions within the simulation environment.
- Return type:
- abstract property messaging: EnvironmentMessaging
This interface enables creating and sending of messages within simulation.
- Return type:
- abstract property resources: EnvironmentResources
This interface gives access to resources, such as actions or exploits.
- Return type:
- abstract property platform_interface: PlatformInterface
This interface provides means for execution platforms to execute actions and to notify the results of actions.
- Return type:
- abstract property infrastructure: EnvironmentInfrastructure
This interface provides access to environment resources that are aimed at behavioral models and to applications utilizing CYST.
- Return type:
- abstract property platform: Platform
Returns the underlying execution platform, which is CYST running on.
- Return type:
- abstractmethod configure(*config_item: ConfigItem, parameters: Dict[str, Any] | None = None) Environment
Configures the environment, according to provided configuration items. This function can be called repeatedly, however, each subsequent call replaces the previous configuration. Therefore, a configuration must be done at once and every later change in the environment setup must be done through the
cyst.api.environment.configuration.EnvironmentConfigurationinterface.- Parameters:
config_item (ConfigItem) – One or more configuration items. The number of items can be arbitrary and it is not order-dependent.
parameters (Dict[str, Any] | None) – Name-value mapping for configuration that supports parametrization. If none is provided, despite parameterizable configuration, default values are used.
- Returns:
The configured environment. Used this way for the shorthand form:
e = Environment.create().configure(*config, parameters)
- classmethod create(platform: str | PlatformSpecification | None = None, run_id: str = '') Environment
Creates a new instance of the environment. A program using CYST can use multiple environments, however, each simulation run happens only in the context of one environment.
- Parameters:
platform (Optional[Union[str, PlatformSpecification]) – A specification of a platform to use as a backend for CYST run. By default, a CYST simulation using a simulated time is used.
run_id (str) – The unique id of the current run. If a non-unique id is selected, it may produce unwanted results when saving the data to a data store.
- Returns:
An environment instance.
cyst.api.environment.clock
- class cyst.api.environment.clock.Clock
Bases:
ABCClock interface provides access to time management of a given platform.
- abstractmethod current_time() float
Returns a current time of a platform as an offset from a specific time in the past. In case of a discrete simulation platform, it will likely return a whole number. For other environments, this will be a fractional number (aka. python’s time() function).
- Returns:
Current time as an offset.
Added in version 0.6.0.
- abstractmethod real_time() datetime
Returns a current time of a platform converted to a real date-time information. In case of a discrete simulation platform this entails a conversion of time offset to a real time. In case o a real-time environment this will likely be only a reading of a system clock.
- Returns:
Current time as a datetime structure.
Added in version 0.6.0.
- abstractmethod timeout(callback: ActiveService | Callable[[Message], Tuple[bool, int]], delay: float, parameter: Any = None) None
Schedule a timeout message. This acts like a time callback and enables inclusion of any kind of data.
- Parameters:
callback – Either a service, which should receive the timeout message, or an arbitrary callback.
delay – The duration of the timeout in simulation time.
parameter – The included data. They will not be modified.
- Returns:
None
Changed in version 0.6.0: Changed delay type to float and added support for generic callbacks.
cyst.api.environment.configuration
This module provides a set of interfaces, which enable procedural configuration of simulation environments. Unlike the cyst.api.configuration module, which declaratively configures the environment only at the initialization, this module enables configuration and manipulation of the environment in all states.
While it is internally used to implement the declarative configuration, it is mainly used by the behavioral models to implement changes in the environment in the reaction to agents’ actions.
- class cyst.api.environment.configuration.EnvironmentConfiguration
Bases:
ABCThis interface is a collection of configuration interfaces for the environment, that are split according to their general functionality.
- abstract property general: GeneralConfiguration
General configuration enables retrieval of objects and their configurations. As such it enables manipulation with all objects that are present in the simulation run.
- Return type:
- abstract property node: NodeConfiguration
Node configuration enables creation and manipulation with nodes and routers.
- Return type:
- abstract property service: ServiceConfiguration
Service configuration enables management of passive and active services.
- Return type:
- abstract property network: NetworkConfiguration
Network configuration enables placing nodes inside the topology and manipulation with connection and sessions. Currently, it is mostly additive, but it will include all manipulation options in the future.
- Return type:
- abstract property exploit: ExploitConfiguration
This interface provides means to manipulate with exploits.
- Return type:
- abstract property action: ActionConfiguration
Action configuration enables creation of action parameter domains. While the actions are fully declarative in their description and their semantics stem from the interpretation given by behavioral models, action parameters enable fine-tuning of actions, that is accessible to automatic tools in a uniform manner.
- Return type:
- abstract property access: AccessConfiguration
Access configuration enables manipulation of authentication and authorization primitives, creation of access schemes and evaluation of authentication tokens.
- Return type:
- abstract property physical: PhysicalConfiguration
Physical configuration enables manipulation with physical locations, their assets, and users within them.
- Return type:
- class cyst.api.environment.configuration.GeneralConfiguration
Bases:
ABCGeneral configuration enables retrieval of objects and their configurations. As such it enables manipulation with all objects that are present in the simulation run.
- abstractmethod get_configuration() List[ConfigItem]
Get the entire configuration of the environment in form of a list containing top level configuration objects, i.e., nodes, connections, and exploits. There are no inter-object references, they are all resolved, so there is a potential duplication.
- Returns:
A complete environment configuration.
- abstractmethod save_configuration(indent: int | None) str
Serializes a configuration into a string representation, that can be saved and later loaded and passed to the configure() method.
- Parameters:
indent (Optional[int]) – The indentation level for pretty-printing. If not provided, the configuration is serialized onto one line. If indent is set to 0, only line breaks are inserted. If indent is set to 1 or more the text is indented accordingly.
- Returns:
A string representation of the environment’s configuration.
- abstractmethod load_configuration(config: str) List[ConfigItem]
Deserializes a string configuration into corresponding configuration items. These are currently not guaranteed to work across versions.
- Parameters:
config (str) – The serialized configuration.
- Returns:
A list of configuration items that can be fed to the configure() function.
- abstractmethod get_configuration_by_id(id: str, configuration_type: Type[ConfigurationObjectType]) ConfigurationObjectType
Get a …Config object by ID.
- Parameters:
id (str) – The ID of the configuration object.
configuration_type (Type[TypeVar('ConfigurationObjectType')]) – A type of the configuration item to get. While not technically necessary, given the state of Python’s type system, it is there to satisfy static typing inspection.
- Returns:
A configuration object with given ID.
- abstractmethod get_object_by_id(id: str, object_type: Type[ObjectType]) ObjectType
Get this back… :param id: :param object_type: :return:
- class cyst.api.environment.configuration.NodeConfiguration
Bases:
ABCNode configuration enables creation and manipulation with nodes and routers.
- abstractmethod create_node(id: str, ip: str | IPAddress = '', mask: str = '', shell: Service = None) Node
Create a node within a simulation. The node itself is empty and must be filled with services before it can interact with the environment. The same goes for its network connection, unless provided in the constructor.
- Parameters:
id (str) – A unique identification of the node within the simulation. Setting a duplicate ID would result in an exception.
ip (Union[str, IPAddress]) – An IP address this node should use. Setting this parameter automatically creates the appropriate network interface. The address can be passed as a string or as an IPAddress, into which it is internally converted from the string.
mask (str) – A network mask to use. This will be used for setting the gateway and routing policy on the node. If the mask is not selected, it gets negotiated during a connection with the router (TODO: check).
shell (Service) – A service that will be acting as a system shell.
- Returns:
An instance of a node in the simulation.
- abstractmethod create_router(id: str, messaging: EnvironmentMessaging) Node
Create a router within simulation. The router is a special type of node, which enables message forwarding and network partitioning.
- Parameters:
id (str) – A unique identification of the node within simulation. Setting a duplicate ID would result in an exception.
messaging (EnvironmentMessaging) – A reference to EnvironmentMessaging
- Returns:
An instance of a router in the simulation.
- abstractmethod create_port(ip: str | IPAddress = '', mask: str = '', index: int = 0, id: str = '') Interface
Create a network port, which can then be used to connect routers to routers.
- Parameters:
ip (Union[str, IPAddress]) – An IP address of the port. If not set, it will be a port without IP and the routing will have to be explicitly specified.
mask (str) – A network mask of the port. It is used to signal the network range serviced by the router.
index (int) – An index the port should have. If a value -1 is selected, the interface is assigned a lowest possible index.
id (str) – A unique identification of the interface within the simulation. If no value is provided, the system will generate a unique one.
- Returns:
An instance of a network port.
- abstractmethod create_interface(ip: str | IPAddress = '', mask: str = '', index: int = 0, id: str = '') Interface
Create a network interface, which can then be used to connect nodes to routers or routers to routers.
- Parameters:
ip (Union[str, IPAddress]) – An IP address of the interface. If not set, it will act as a DHCP interface for nodes and an IP-less port for routers.
mask (str) – A network mask of the interface. In case of a node interface it will be used for setting the gateway and routing policy on the node. If the mask is not selected, it gets negotiated during a connection with the router. In case of router port, the mask is used to determine the pool for DHCP addresses.
index (int) – An index the port should have, once assigned to a node. If a value -1 is selected, the interface is assigned a lowest possible index.
id (str) – A unique identification of the interface within the simulation. If no value is provided, the system will generate a unique one.
- Returns:
An instance of a network interface.
- abstractmethod create_route(net: IPNetwork, port: int, metric: int, id: str = '') Route
Create a route, which determines through which port messages directed to particular network get sent.
- Parameters:
net (IPNetwork) – A destination network, which is being routed through the specified port.
port (int) – A port index. If a nonexistent port is selected, it will raise an exception, when a message will be routed through it.
metric (int) – A metric for the route. Routes with lower metric get selected when there is an overlap in their networks. In case of metric equivalence, more specific routes are selected.
id (str) – A unique identification of the route within the simulation. If no value is provided, the system will generate a unique one.
- Returns:
A route to be used in router.
- abstractmethod add_interface(node: Node, interface: Interface, index: int = -1) int
Assigns a network interface instance to a node.
- Parameters:
- Returns:
An index, where the interface was assigned.
- abstractmethod set_interface(interface: Interface, ip: str | IPAddress = '', mask: str = '') None
Sets parameters of an interface instance.
- Parameters:
interface (Interface) – The instance of the interface.
ip (Union[str, IPAddress]) – A new IP address to use. Setting this to an empty string will effectively erase the IP address from the interface. In that case, it can only work in routers with explicit routing.
mask (str) – A new network mask.
- Returns:
None
- abstractmethod add_service(node: Node, *service: Service) None
Add a service to the node. The engine expects that there aren’t two services of the same name on one node. In such case, the effects are undefined.
- abstractmethod remove_service(node: Node, *service: Service) None
Remove a service from the node.
- Parameters:
node (Node) – An instance of a node to remove the service from.
sertice – One or more service instances to remove.
- Returns:
None
- abstractmethod set_shell(node: Node, service: Service) None
Set given service as a shell. Unlike the method add_service, set_shell does not produce undefined results, when a service already present at the node is set as a shell.
- abstractmethod add_traffic_processor(node: Node, processor: ActiveService) None
Add a service to a traffic processor queue. Traffic processors process messages incoming into a node before any evaluation takes place. There can be multiple traffic processors on one node and their order depends on the order of add_traffic_processor calls. The first one added, processes the traffic first, and so on…
Any active service can be set as a traffic processor. Traffic processors are free to change the contents of messages and unless they return False from their process_message() function that message is passed to next processors or to the node.
- Parameters:
node (Node) – An instance of the node where traffic processor should be added.
processor (ActiveService) – An instance of an active service which will act as a traffic processor.
- Returns:
None
- abstractmethod add_routing_rule(node: Node, rule: FirewallRule) None
Adds a rule for source-destination routing. This effectively bypasses the routing rules and enables custom port forwarding.
- TODO
This is only temporary - first, it is leaking implementation detail to outside and second, it is completely stupid, as router should be a designated active service and should provide configuration interface.
- Parameters:
node (Node) – An instance of a router. Although the type is set as a Node here, this function can only be called on routers. Trying to add a routing rule to an ordinary node would do nothing.
rule (FirewallRule) – A firewall rule, which coincidentally has all the necessary ingredients for implementation of source-destination routing. See the TODO on why this is a stupid idea.
- Returns:
None
- abstractmethod set_routing_policy(node: Node, policy: FirewallPolicy) None
Sets a default routing policy for source-destination routing.
The same comment regarding the stupidity of this interface applies as an function add_routing_rule().
- Parameters:
node – An instance of a router. Although the type is set as a Node here, this function can only be called on routers. Trying to assign a routing policy to an ordinary node would do nothing.
policy (FirewallPolicy) – A firewall policy, which coincidentally has all the necessary ingredients for implementation of source-destination routing policy. See the add_routing_rule() on why this is a stupid idea.
- Returns:
None
- abstractmethod list_routes(node: Node) List[Route]
List all the routes currently set at a router.
- TODO
This will be changed in the future, after router is implemented as an active service with its own interface.
- Parameters:
node (Node) – The router to get routes from. Although the type is set as a Node here, this function can only be called on routers. Trying to list routes from an ordinary node would do nothing.
- Returns:
A list of routes.
- class cyst.api.environment.configuration.ServiceConfiguration
Bases:
ABCService configuration enables management of passive and active services.
- abstractmethod create_active_service(type: str, owner: str, name: str, node: Node, service_access_level: AccessLevel = AccessLevel.LIMITED, configuration: Dict[str, Any] | None = None, id: str = '') Service | None
Creates an active service. These include anything from traffic processors to agents.
- Parameters:
type (str) – A type of the service, which is a unique identification among services.
id (str) – An ID that will be given to the service and which must be unique within the simulation environment.
owner (str) – An identity that will own the service at the node. While it should be an identity that is present at the node, this is currently not controlled in any way, because the whole identity business is not yet sorted out.
name (str) – The name of the service as it was registered into the system. (see cyst.api.host.service.ActiveServiceDescription)
node (Node) – An instance of a node where the service will reside in the end. There is a technical limitation that lies behind this requirement. If it weren’t there, everything would be done in the add_service() call.
service_access_level (AccessLevel) – An access level for the service. This mostly concerns the resources of the Node it can access.
configuration (Optional[Dict[str, Any]]) – A dictionary of configuration parameters. There are no limitations to the param/value pairs, as they are directly passed to function creation function. (see cyst.api.host.service.ActiveServiceDescription)
id – An ID that will be given to the service and which must be unique within the simulation environment. If no ID is provided a unique one is generated.
- Returns:
An instance of an active service, or null if failed to create one.
- abstractmethod get_service_interface(service: ActiveService, control_interface_type: Type[ActiveServiceInterfaceType]) ActiveServiceInterfaceType
Active services can provide an interface, which enables a finer control over their function than a rather limited cyst.api.host.service.ActiveService interface.
Due to python’s handling of types and interfaces, you can always just call the functions of the service directly, without going through the hassle of interface acquisition, but such approach would not pass through a static verification.
Example:
from cyst.api.environment.environment import Environment from cyst.services.scripted_attacker.main import ScriptedAttackerControl env = Environment.create() node = env.configuration.node.create_node("node1") service = env.configuration.service.create_active_service("attacker1", "attacker", "scripted_attacker", node) ctrl = env.configuration.service.get_service_interface(service.active_service, ScriptedAttackerControl) ctrl.execute_action(...)
- Parameters:
service (ActiveService) – An instance of an active service. Please consult the example and the Service interface to prevent unwanted surprises (.active_service).
control_interface_type (Type[TypeVar('ActiveServiceInterfaceType')]) – A type of the interface that should be obtained from the service. Note that a service can provide multiple interfaces.
- Returns:
An interface of a service.
- abstractmethod get_service_type(service: Service) str
Returns a type of given service.
- Parameters:
service (Service) – A service instance.
- Returns:
A service type under which it is registered in the system, i.e., the type attribute of ActiveService, or a “PassiveService” string if it is a passive service.
- abstractmethod create_passive_service(type: str, owner: str, version: str = '0.0.0', local: bool = False, service_access_level: AccessLevel = AccessLevel.LIMITED, id: str = '') Service
Create a passive service.
- Parameters:
type (str) – A type of the service, such as lighttpd or bash. The type is relevant for mapping exploits.
owner (str) – An identity that will own the service at the node. While it should be an identity that is present at the node, this is currently not controlled in any way, because the whole identity business is not yet sorted out.
version (str) – The version of the service. The format of the version should be compatible with semantic versioning scheme. TODO: Extend the signature to Union[str, VersionInfo]
local (bool) – An indication, whether the service is accessible from outside the node.
service_access_level (AccessLevel) – An access level of the service. This mostly concerns the resources than can be accessed in case of service compromise.
id (str) – A unique ID within the simulation. An ID is generated if not provided.
- Returns:
An instance of passive service.
- abstractmethod update_service_version(service: PassiveService, version: str = '0.0.0') None
Changes the service version to a new value. This function is primarily meant as a way to simulate updates or patching of already running services.
- Parameters:
service (PassiveService) – An instance of the passive service.
version (str) – A new value of the version. The format of the version should be compatible with semantic versioning scheme. TODO: Extend the signature to Union[str, VersionInfo]
- Returns:
None
- abstractmethod set_service_parameter(service: PassiveService, parameter: ServiceParameter, value: Any) None
Sets a parameter of an existing passive service. The parameters are chosen from a parametrization domain defined by the ServiceParameter flags.
- Parameters:
service (PassiveService) – An instance of the passive service.
parameter (ServiceParameter) – A type of the parameter to set.
value (Any) – A value of the parameter. For allowed values, consult cyst.api.environment.configuration.ServiceParameter.
- Returns:
None
- abstractmethod create_data(id: str | None, owner: str, path: str, description: str) Data
Creates a data. Currently, this is a very rudimentary approach and future updates are expected to provide more sophisticated mechanisms for data description and manipulation.
- Parameters:
id (Optional[str]) – An optional identification of the data.
owner (str) – An identity of the owner of the data. This should be an identity existing within the simulation (not necessarily on the node and service where the data will reside), as the access to the data should be checked against the name in the authentication token, which has to be the same as the owner. [That “should” here means that it is dependent on the implementation of behavioral models.]
path (str) – A path to the data, which should be unique among all data within one service.
description (str) – A textual description of the data, which currently enables differentiation between data instances.
- Returns:
An instance of data.
- abstractmethod public_data(service: PassiveService) List[Data]
Gets access to the data that should be available on the service without the need for authentication. This can be used both to get and set the data.
- Parameters:
service (PassiveService) – An instance of the passive service.
- Returns:
A list of public data instances on the service.
- abstractmethod private_data(service: PassiveService) List[Data]
Gets access to the data that should be available on the service only after authentication. This can be used both to get and set the data.
- Parameters:
service (PassiveService) – An instance of the passive service.
- Returns:
A list of private data instances on the service.
- abstractmethod public_authorizations(service: PassiveService) List[Authorization]
Gets access to public authorizations present at the service.
Warning
This function is deprecated and will be removed soon, as it does not conform to the current authentication/authorization framework.
- Parameters:
service (PassiveService) – An instance of the passive service.
- Returns:
A list of publicly available authorization instances.
- abstractmethod private_authorizations(service: PassiveService) List[Authorization]
Gets access to private authorizations present at the service.
Warning
This function is deprecated and will be removed soon, as it does not conform to the current authentication/authorization framework.
- Parameters:
service (PassiveService) – An instance of the passive service.
- Returns:
A list of privately available authorization instances.
- abstractmethod sessions(service: PassiveService) List[Session]
Gets access to sessions that are connected to the service. These sessions can either be the ones created as a part of the initialization process, or those that were created following the activities in the simulation.
- Parameters:
service (PassiveService) – An instance of the passive service.
- Returns:
A list of sessions connected to the service.
- abstractmethod provides_auth(service: Service, auth_provider: AuthenticationProvider) None
Adds an authentication provider to a service.
- TODO
This function, if it is really intended to stay, must be renamed to something better, such as add_auth_provider. Also the parameter type should be checked, because the implementation conflates Service and PassiveService.
- Parameters:
service (Service (but should be PassiveService)) – An instance of the passive service.
auth_provider (AuthenticationProvider) – An authentication provider to add.
- Returns:
None
- abstractmethod set_scheme(service: PassiveService, scheme: AccessScheme) None
Sets and authentication scheme at the service. More on authentication schemes at the user’s documentation or in the documentation of cyst.api.logic.access.
- Parameters:
service (PassiveService) – An instance of the passive service.
scheme (AccessScheme) – An instance of the access scheme.
- Returns:
None
- class cyst.api.environment.configuration.NetworkConfiguration
Bases:
ABCNetwork configuration enables placing nodes inside the topology and manipulation with connection and sessions. Currently, it is mostly additive, but it will include all manipulation options in the future.
- abstractmethod add_node(node: Node) None
Adds a node into the topology. After a node is created, it must be added to the simulation topology. Otherwise it will not be included in messaging. Note that this is done implicitly when using declarative configuration, so this mostly concerns scenarios, such as honeypot deployment.
- Parameters:
node (Node) – An instance of the node.
- Returns:
None
- abstractmethod add_connection(source: Node, target: Node, source_port_index: int = -1, target_port_index: int = -1, net: str = '', connection: Connection | None = None) Connection
Adds a connection between two nodes, provided each one has a network port available. If one of the nodes is router, it may trigger DHCP address assignment, depending on the settings of node interfaces.
- Parameters:
source (Node) – An instance of the source node. Connections are currently bi-directional, so it does not matter which one is the source and which one is the destination.
target (Node) – An instance of the destination node.
source_port_index (int) – An index of the interface at the source node. If the index does not point to an existing interface, an exception will be thrown.
target_port_index (int) – An index of the interface at the destination node. If the index does not point to an existing interface, an exception will be thrown.
net (str) – A network mask specification, used by a router (if one is present) to determine a correct address range. This parameter is not necessary, if all addresses are fully specified in the interfaces.
connection (Connection) – An instance of a connection. This parameter enables passing a specific connection instance, which has, e.g., specific connection properties. If this parameter is omitted, then a new connection is automatically created.
- Returns:
An instance of a connection that was established between selected nodes.
- abstractmethod get_connections(node: Node, port_index: int | None = None) List[Connection]
Gets connections that are connected to the node at the port index, if specified.
- Parameters:
node (Node) – An instance of the node.
port_index (Optional[int]) – An index of the port.
- Returns:
A list of connections that are connected to the node.
- abstractmethod create_session(owner: str, waypoints: List[str | Node], src_service: str | None = None, dst_service: str | None = None, parent: Session | None = None, defer: bool = False, reverse: bool = False, id: str | None = None) Session | None
Creates a fixed session in the simulated infrastructure. This session ignores the routing limitations imposed by router configuration. However, the creation mechanism checks if there exists a connection between each of session waypoints and it selects the appropriate interfaces to realize the connection through.
- Parameters:
owner (str) – The owner of the session. This parameter is used to prevent sharing of sessions, but it will likely be deprecated in future versions, because it does not work well when appending sessions through exploiting.
waypoints (List[Union[str, Node]]) – A list of node instances or their IDs, which constitute the path of the session. As per the description, there has to be a connection between all subsequent tuples of waypoints.
src_service (Optional[str]) – An ID of the service that is the anchor at the origin of the session. This service can tear down the session at will.
dst_service (Optional[str]) – An ID of the service that is the anchor at the destination of the session. This service can tear down the session at will.
parent (Optional[Session]) – A parent session that can be optionally used as a first part/head of the session.
defer (bool) – I this parameter is set to False, the system attempts to create the session immediately. If set to False, the creation is deferred to the environment init phase, when all the waypoints should already be instantiated.
reverse (bool) – Construct the session in the reverse order, i.e., as if it was constructed as a reverse shell.
id (str) – An explicit ID of the session. If none is provided, it is autogenerated.
- Returns:
An instance of a created session (unless deferred, than it always return null)
- abstractmethod append_session(original_session: Session, appended_session: Session) Session
Creates a new session by appending a two sessions together.
- Parameters:
- Returns:
A new session that is a combination of both the original ones.
- abstractmethod create_session_from_message(message: Message, reverse_direction: bool = False) Session
Establishes a new session from the path the message travelled. This function is mostly used by behavioral models to create new sessions in response to messages coming from attackers.
- Parameters:
message (Message) – An instance of the message.
reverse_direction (bool) – Whether the direction of the shell is reversed or not.
- Returns:
A new session.
- class cyst.api.environment.configuration.ExploitConfiguration
Bases:
ABCThis interface provides means to manipulate with exploits.
- abstractmethod create_vulnerable_service(id: str, min_version: str = '0.0.0', max_version: str = '0.0.0') VulnerableService
Create a definition of a vulnerable service, that is used for exploit specification
- Parameters:
name (str) – A name of the service. It is an equivalent of PassiveService/PassiveServiceConfig name.
min_version (str) – A minimum version of the service that is vulnerable. Even though the type supports any string, using anything else than string representation of a semantic version will lead to problems.
max_version (str) – A maximum version of the service that is vulnerable. Even though the type supports any string, using anything else than string representation of a semantic version will lead to problems.
- Returns:
A vulnerable service description.
- abstractmethod create_exploit_parameter(exploit_type: ExploitParameterType, value: str = '', immutable: bool = False) ExploitParameter
Creates an exploit parameter.
Exploit parameter either represents a specification of an exploit, which can’t be modified by a user, but is taken into account by exploit evaluation mechanisms (e.g., if the impact is one user or all users), or provides a mean for a user to supply additional information necessary for full execution of the exploit (e.g., identity of a user to impersonate).
- Parameters:
type (ExploitParameterType) – A type of the exploit parameter.
value (Optional[str]) – A value of the parameter.
immutable (bool) – A flag indicating, whether a user can change the value of the parameter.
- Returns:
An instance of exploit parameter.
- abstractmethod create_exploit(id: str = '', services: List[VulnerableService] = None, locality: ExploitLocality = ExploitLocality.NONE, category: ExploitCategory = ExploitCategory.NONE, *parameters: ExploitParameter) Exploit
Creates a working exploit.
If a definition of exploit exists, then a services it refers to are vulnerable, as long as their version match. Patching the service and bumping a version over the max vulnerable version is the only countermeasure.
- Parameters:
id (str) – A unique identification of the exploit.
services (List[VulnerableService]) – A list of services that are vulnerable to this exploit.
locality (ExploitLocality) – Determines if the exploit can be used locally or remotely.
category (ExploitCategory) – Determines the category of the exploit.
parameters (Optional[List[ExploitParameter]]) – An optional list of exploit parameters.
- Returns:
An instance of the exploit.
- abstractmethod add_exploit(*exploits: Exploit) None
Adds an exploit to the exploit store, where it can be accessed by the services. Unless an exploit is added to the store, it cannot be used, even though it was created.
- Parameters:
exploits (Exploit) – One or more exploit instances to be added.
- Returns:
None
- abstractmethod clear_exploits() None
Removes all exploits from exploit store.
- Returns:
None
- class cyst.api.environment.configuration.ActionConfiguration
Bases:
ABCAction configuration enables creation of action parameter domains. While the actions are fully declarative in their description and their semantics stem from the interpretation given by behavioral models, action parameters enable fine-tuning of actions, that is accessible to automatic tools in a uniform manner.
- abstractmethod create_action_parameter_domain_any() ActionParameterDomain
Create an action parameter domain that can accept any parameter. This domain should be avoided at all costs, because it does not provide anything for automated tools to work with.
- Returns:
An unbounded parameter domain.
- abstractmethod create_action_parameter_domain_range(default: int, min: int, max: int, step: int = 1) ActionParameterDomain
Creates a parameter domain that is represented by a range of numbers. Ideal for expressing things like port ranges.
- Parameters:
default (int) – A default value of the domain.
min (int) – A minimal range value.
max (int) – A maximal range value.
step (int) – Enables to include only every step-th number between min and max.
- Returns:
A parameter domain consisting of range of numbers.
- abstractmethod create_action_parameter_domain_options(default: Any, options: List[Any]) ActionParameterDomain
Creates a parameter domain that is represented by a set of possible values. The values are not limited in any way, but this enables automated tools to select from them.
- Parameters:
default (Any) – A default value of the domain.
options (List[Any]) – A list of values, which constitute the domain.
- Returns:
A parameter domain consisting of set of values.
- class cyst.api.environment.configuration.AccessConfiguration
Bases:
ABCAccess configuration enables manipulation of authentication and authorization primitives, creation of access schemes and evaluation of authentication tokens.
- abstractmethod create_authentication_provider(provider_type: AuthenticationProviderType, token_type: AuthenticationTokenType, security: AuthenticationTokenSecurity, ip: IPAddress | None, timeout: int, id: str = '') AuthenticationProvider
Authentication provider represents an authentication mechanism that can be employed in services via the access scheme mechanism.
- Parameters:
provider_type (AuthenticationProviderType) – The type of authentication provider.
token_type (AuthenticationTokenType) – The type of tokens that are employed by this authentication provider.
token_security (AuthenticationTokenSecurity) – Security mechanism applied to stored tokens.
ip (Optional[IPAddress]) – An optional IP address, which is intended for remote or federated providers. It represents an IP address where this provider can be accessed.
timeout (int) – A number of simulated time units that can elapse from the initiation of authentication exchange before the attempt is discarded as unsuccessful.
id (str) – A unique identification of the provider within the simulation. If no value is provided, the system will generate a unique one.
- Returns:
An authentication provider instance.
- abstractmethod create_authentication_token(type: AuthenticationTokenType, security: AuthenticationTokenSecurity, identity: str, is_local: bool) AuthenticationToken
Creates an authentication token for a given identity. This token is given a unique identifier, which distinguishes it from other tokens.
Warning
The documentation is missing the description of the is_local parameter and it implications
- Parameters:
type (AuthenticationTokenType) – A type of the authentication token.
security (AuthenticationTokenSecurity) – A level of security for the authentication token.
identity – A identity this token is bound to. In theory, no identity needs to be provided (such as access code to doors). However, not using it here may have unintended consequences.
is_local (bool) – No idea…
- Returns:
An instance of authentication token.
- abstractmethod register_authentication_token(provider: AuthenticationProvider, token: AuthenticationToken) bool
Registers an authentication token with the authentication provider. After that, anyone possessing the token can authenticate against the provider.
- Parameters:
provider (AuthenticationProvider) – An instance of the authentication provider.
token (AuthenticationToken) – An instance of the authentication token.
- Returns:
Indication, whether registration was successful.
- abstractmethod unregister_authentication_token(token_identity: str, provider: AuthenticationProvider) None
Unregisters authentication token from given provider based on given token identity.
- Parameters:
token_identity (str) – An identity for token to be unregistered from provider.
provider (AuthenticationProvider) – An authentication provider to unregister token from.
- Returns:
None
- abstractmethod create_and_register_authentication_token(provider: AuthenticationProvider, identity: str) AuthenticationToken | None
A convenience function that combines the effects of create_authentication_token() and register_authentication_token().
- Parameters:
provider (AuthenticationProvider) – An instance of the authentication provider.
identity (str) – A identity the created token is bound to. In theory, no identity needs to be provided (such as access code to doors). However, not using it here may have unintended consequences.
- Returns:
An instance of authentication token that is already registered.
- abstractmethod create_authorization(identity: str, access_level: AccessLevel, id: str, nodes: List[str] | None = None, services: List[str] | None = None) Authorization
Creates and authorization for a given identity. The authorization gives the identity access to selected nodes and services with a given access level.
- Parameters:
identity (str) – An identity for whom the authorization is created.
access_level (AccessLevel) – An access level this authorization provides.
id (str) – A unique identifier of this authorization. TODO: I have no idea, what is the purpose.
nodes (Optional[List[str]]) – A list of node ids this authorization works on. This is intended for federated identities, which can are shared among different nodes and services. For local authentication providers, this parameters is of no use.
services (Optional[List[str]]) – A list of service ids this authorization works on. This is intended for federated identities, which can are shared among different nodes and services. For local authentication providers, this parameters is of no use.
- Returns:
An authorization token.
- abstractmethod create_access_scheme(id: str = '') AccessScheme
Creates an empty access scheme. The access scheme is a combination of authentication providers, which use a supplied authorizations. The access scheme provides means to describe multiple authentication schemes within one service or multi-factor authentication.
- Parameters:
id (str) – A unique identification of the scheme within the simulation. If no value is provided, the system will generate a unique one.
- Returns:
An empty access scheme.
- abstractmethod add_provider_to_scheme(provider: AuthenticationProvider, scheme: AccessScheme) None
Adds an authentication provider to the access scheme.
- Parameters:
provider (AuthenticationProvider) – An authentication provider.
scheme (AccessScheme) – An access scheme to add provider to.
- Returns:
None
- abstractmethod add_authorization_to_scheme(auth: Authorization, scheme: AccessScheme) None
Adds an authorization to the access scheme.
- Parameters:
auth (Authorization) – An instance of authorization.
scheme (AccessScheme) – An access scheme to add authorization to.
- Returns:
None
- abstractmethod remove_authorization_from_scheme(auth: Authorization, scheme: AccessScheme) None
Removes given authorization from given scheme by setting its access level to AccessLevel.NONE
- Parameters:
auth (Authorization) – An authorization to be removed from scheme.
scheme (AccessScheme) – A scheme.
- Returns:
None
- abstractmethod evaluate_token_for_service(service: Service, token: AuthenticationToken, node: Node, fallback_ip: IPAddress | None) Authorization | AuthenticationTarget | None
Evaluates if a token authenticates against a service. For single-factor authentications, this function returns either a working authorization token or none, depending on success. For multi-factor authentications, if it is the last factor, then it behaves as a single-factor authentication. If it is not, then it will either return a next authentication target in given scheme or none, depending on success.
- TODO
Add the description of fallback_ip.
- Parameters:
service (Service) – An instance of the service the evaluation is against.
token (AuthenticationToken) – An instance of the authentication token.
node (Node) – An instance of the node where the service resides on.
fallback_ip (Optional[IPAddress]) – No idea
- Returns:
Either a working authorization, a next target, or just none if the authentication was not successful.
- abstractmethod disable_authentication_token(provider: AuthenticationProvider, token: AuthenticationToken, time: int) None
Disables given token until given simulation time.
- Parameters:
provider (AuthenticationProvider) – An authentication provider that contains token to be disabled.
token (AuthenticationToken) – An authentication token to be disabled.
time (int) – Simulation time
- Returns:
None
- abstractmethod enable_authentication_token(provider: AuthenticationProvider, token: AuthenticationToken) None
Enables given token.
- Parameters:
provider (AuthenticationProvider) – An authentication provider that contains token to be enabled.
token (AuthenticationToken) – An authentication token to be enabled.
- Returns:
None
- abstractmethod create_service_access(service: Service, identity: str, access_level: AccessLevel, tokens: List[AuthenticationToken] = None) List[AuthenticationToken] | None
Create a means to access the given passive service by registering authentication tokens under the given identity.
TODO: Currently works only for local providers.
- Parameters:
service (PassiveService) – A passive service to grant access to.
identity (str) – An identity of the user which will gain the access. It must not be already present in one of the access schemes.
access_level (AccessLevel) – The level of access which will be created.
tokens (List[AuthenticationToken]) – Tokens to be optionally used instead of creating new ones.
- Returns:
List of authentication tokens if successful, None otherwise.
- abstractmethod modify_existing_access(service: Service, identity: str, access_level: AccessLevel) bool
Modify the access level of the given passive service. No new tokens are created.
TODO: Currently works only for local providers.
- Parameters:
service (PassiveService) – A passive service to grant access to.
identity (str) – An identity of the user which access will be modified. It must be already present at one of the access scheme.
access_level (AccessLevel) – The level of access which will be modified.
- Returns:
True if successful, False otherwise.
- class cyst.api.environment.configuration.PhysicalConfiguration
Bases:
ABCPhysical configuration enables manipulation with physical locations, their assets, and users within them.
- abstractmethod create_physical_location(location_id: str | None) PhysicalLocation
Creates a new physical location. This location is empty an inaccessible.
- Parameters:
location_id (str | None) – An identification of a location. If not provided, the id is autogenerated.
- Returns:
A physical location handle.
- abstractmethod get_physical_location(location_id: str) PhysicalLocation | None
Returns a physical location handle by given id.
- Parameters:
location_id (str) – An identification of a location.
- Returns:
A physical location handle if it exists with the given id, or None otherwise.
- abstractmethod get_physical_locations() List[PhysicalLocation]
Returns all physical locations that are present in the current run.
- Returns:
List of physical locations.
- abstractmethod remove_physical_location(location_id: str) None
Removes a physical locations. Physical connections associated with it are removed as well. If there are assets and users at the physical location, there are moved to a limbo with other unassigned assets.
- Parameters:
location_id (str) – An id of the location.
- Returns:
None. Throws when attempting to remove nonexistent location.
- abstractmethod create_physical_access(identity: str, time_from: datetime | None, time_to: datetime | None) PhysicalAccess
Creates a physical access specification. This specification can be used multiple times for different locations.
- Parameters:
identity (str) – The identity of the user for which the access is being made. The identity is not checked for existence, therefore, access for non-existent users can be made.
time_from (datetime | None) – A specification of a time of a day (the date part is ignored) from which the access is granted. If no time is provided, then 00:00:00 is assumed.
time_to (datetime | None) – A specification of a time of a day (the date part is ignored) to which the access is granted. If no time is provided, then 23:59:59 is assumed.
- Returns:
A physical access handle.
- abstractmethod add_physical_access(location_id: str, access: PhysicalAccess) None
Adds physical access to a given location. Accesses may overlap, asi it does not matter, because they all represent an ALLOW rule.
- Parameters:
location_id (str) – The ID of a location where to add the access. Throws if nonexistent.
access (PhysicalAccess) – A physical access handle.
- Returns:
None
- abstractmethod get_physical_accesses(location_id: str) List[PhysicalAccess]
Lists all accesses that are in effect at a given location.
- Parameters:
location_id (str) – The ID of a location to list accesses from. Throws if nonexistent.
- Returns:
Physical access handles for the given location.
- abstractmethod remove_physical_access(location_id: str, access: PhysicalAccess) None
Removes physical access from the given location.
- Parameters:
location_id (str) – The ID of a location to remove accesses from. Throws if nonexistent.
access (PhysicalAccess) – A physical access handle.
- Returns:
None
- abstractmethod add_physical_connection(origin: str, destination: str, travel_time: Duration) None
Creates a new physical connection between two locations. If such connection already exists, a new connection is not created.
- Parameters:
origin (str) – An id of a location which is the first endpoint of the connection. Throws if nonexistent.
destination (str) – An id of a location which is the second endpoint of the connection. Throws if nonexistent.
travel_time (Duration) – A duration needed to traverse the connection.
- Returns:
None
- abstractmethod remove_physical_connection(origin: str, destination: str) None
Removes a physical connection between two locations. If the connection does not exist, this is no-op.
- Parameters:
origin (str) – An id of a location which is the first endpoint of the connection. Throws if nonexistent.
destination (str) – An id of a location which is the second endpoint of the connection. Throws if nonexistent.
- Returns:
None
- abstractmethod get_physical_connections(origin: str, destination: str | None) List[PhysicalConnection]
Get a list of physical connections between locations.
- Parameters:
origin (str) – An id of a location which is one of the endpoints of the physical connection. Throws if nonexistent.
destination (str) – An id of a location which is another one of the endpoints of the physical connections. If no destination is specified, then this function returns all physical connections from/to an origin. Throws is nonexistent.
- Returns:
A list of physical connections.
- abstractmethod place_asset(location_id: str, asset: str) None
Add an asset to a location. For this purpose, users are treated as assets, much like nodes and others. This is a deus ex machina function. The asset appears in the location instantaneously. The function only controls if the asset is already present elsewhere. In such case the asset is removed from the other location and placed in this one. If the asset is already assigned to the given location, nothing happens.
- Parameters:
location_id (str) – An ID of a location where to place the asset. Throws if nonexistent.
asset (str) – An ID of the asset to add to a location.
- Returns:
None
- abstractmethod remove_asset(location_id: str, asset: str) None
Removes an asset from a location. For this purpose, users are treated as assets, much like nodes and others. This is a deus ex machina function. The asset is removed from the location instantaneously and is placed in a limbo.
- Parameters:
location_id (str) – An ID of a location from which to remove the asset. Throws if nonexistent.
asset (str) – An ID of the asset to remove from a location.
- Returns:
None
- abstractmethod move_asset(origin: str, destination: str, asset: str) Tuple[bool, str, str]
Moves an asset between two locations. For this purpose, users are treated as assets, much like nodes and others. Before the move, it is checked, whether there is a physical connection between the locations. If so, then the asset traverses the connection for given duration, and if it is the User, it is checked, whether they have access rights.
All assets are traversing the connection for the same time, so for example, if you want to mimic a moving of a piece of hardware between two locations, do not forget to add reasonable delays before and after the move to simulate packing and unpacking.
- Parameters:
origin (str) – An id of a location which is the first endpoint of the connection. Throws if nonexistent.
destination (str) – An id of a location which is the second endpoint of the connection. Throws if nonexistent.
asset (str) – An ID of the asset to move between locations.
- Returns:
A tuple representing (<was the move successful?>, <what is the location of asset after the move>, <a problem description if there was any>)
- abstractmethod get_assets(location_id: str) List[str]
Get the list of assets present at the specified location.
- Parameters:
location_id (str) – A name of a location from which to get the assets. Throws if nonexistent.
- Returns:
A list of assets.
- abstractmethod get_location(asset: str) str
Get the location of a given asset.
- Parameters:
asset (str) – The ID of the asset for which you want the location.
- Returns:
The id of a location, or an empty string if the asset is in limbo.
- class cyst.api.environment.configuration.RuntimeConfiguration(data_backend: str = 'memory', data_backend_params: ~typing.Dict[str, str] = <factory>, data_batch_storage: bool = False, run_id: str = <factory>, run_id_log_suffix: bool = False, config_id: str = '', config_filename: str = '', max_running_time: float = 0.0, max_action_count: int = 0, other_params: ~typing.Dict[str, str] = <factory>)
Bases:
objectRuntime configuration represents parametrization of running core instances. This configuration can come from multiple sources, e.g., environment variables, files, or command line parameters.
- Parameters:
data_backend (str) – Specification of the backend for the data store. CYST by default provides two data store backends - ‘memory’ and ‘sqlite’.
data_backend_params (Dict[str, str]) – Parametrization of the data backend. Once something else than parameter-less memory backend works, it will be documented here.
data_batch_storage (bool) – If set to true, data to be stored in the backend are first stored into the memory and only then transferred to the chosen backend.
run_id (str) – The current run id, regardless of it was autogenerated, or provided by a user.
run_id_log_suffix (bool) – If set to true, run_id will be a part of log file names.
config_id (str) – An identifier of a configuration for the current run, if the configuration is retrieved from a database.
config_filename (str) – A path to a file where a configuration for the current run is present.
max_running_time (float) – An upper limit on an execution time of a run. A platform time is considered, not the real time. The run is not guaranteed to finish at exactly the specified time, rather it will gracefully finish if the running time is exceeded.
max_action_count (int) – An upper limit on the number of executed actions by any actor. When this count is reached, the run terminates. Only the top-level actions (i.e., not actions executed within composite actions) are counted and the run is not guaranteed to finish at exactly the specified action count. Rather, it will gracefully finish if the action count is exceeded.
other_params (Dict[str, str]) – A dictionary of parameters that are not directly consumed by the environment but are passed to the other components, agents, etc.
cyst.api.environment.control
- class cyst.api.environment.control.EnvironmentState(*values)
Bases:
EnumState of the environment
State transition diagram:
reset() terminate() ┌────────── TERMINATED ◄───────────┐ │ ▲ │ │ terminate()│ │ ▼ │ ──pause()──► │ CREATED ──init()─► INIT ──run()─► RUNNING PAUSED ▲ │ ◄──run()─── │ │ │ ▼ └────────── FINISHED reset()- Possible values:
- CREATED:
The environment was jus created.
- INIT:
The environment was initialized and is ready to run.
- RUNNING:
The environment is currently running a simulation.
- PAUSED:
The environment is paused. If unpaused, the messages on stack will be sent and simulation resumes.
- FINISHED:
The environment finished a simulation run. This means either no more messages on stack, or running past the specified time.
- TERMINATED:
The environment was forcefully stopped. It cannot be resumed, but its internal state can be investigated.
- class cyst.api.environment.control.EnvironmentControl
Bases:
ABCEnvironmentControl provides mechanisms to control the execution of actions within the simulation environment.
- Availability:
- Available:
creator
- Hidden:
agents, models
- abstract property state: EnvironmentState
Provides the current state of the environment.
- Returns:
State of the environment
- Return type:
- abstractmethod init() Tuple[bool, EnvironmentState]
Initializes the environment for the first time. The environment must be in the CREATED state. The following invocations do nothing and silently return true.
- Returns:
A tuple indicating, whether the operation was successful and which state the environment ended in.
- abstractmethod commit() None
Stores the information of the currently executed run into the data store. This can only be executed from the FINISHED or TERMINATED state.
- Returns:
None
- abstractmethod reset(run_id: str = '238106fa-be4f-40e0-ae74-ee1c62608d26') Tuple[bool, EnvironmentState]
Resets the environment for another run. Only a previously FINISHED or TERMINATED run can be reset.
- Parameters:
run_id (str) – The unique id of the current run. If a non-unique id is selected, it may produced unwanted results when saving the data to a data store.
- Returns:
A tuple indicating, whether the operation was successful and which state the environment ended in.
- abstractmethod run() Tuple[bool, EnvironmentState]
Starts or resumes the message processing in the current run. If the environment is in the INIT state, it activates the active services. If it is in INIT or PAUSED state, it begins message processing and transitions into the RUNNING state.
- Returns:
A tuple indicating, whether the operation was successful and which state the environment ended in.
- abstractmethod pause() Tuple[bool, EnvironmentState]
Invokes an explicit transition into the PAUSED state and temporarily halts the message processing. Can only be applied in the running state.
- Returns:
A tuple indicating, whether the operation was successful and which state the environment ended in.
- abstractmethod terminate() Tuple[bool, EnvironmentState]
Halts the message processing and transitions the environment into the TERMINATED state. From this state the environment cannot be re-run.
- Returns:
A tuple indicating, whether the operation was successful and which state the environment ended in.
- abstractmethod add_pause_on_request(id: str) None
Adds an explicit interrupt to message processing, whenever a service sends a request. Transitions the environment into the PAUSED state. Used mainly in tests to break from the run().
- Parameters:
id – A fully qualified id of a service, i.e., also containing the node id.
- Returns:
None
- abstractmethod remove_pause_on_request(id: str) None
Removes an explicit interrupt to message processing, whenever a service sends a request.
- Parameters:
id – A fully qualified id of a service, i.e., also containing the node id.
- Returns:
None
- abstractmethod add_pause_on_response(id: str) None
Adds an explicit interrupt to message processing, whenever a service receives a response. Transitions the environment into the PAUSED state. Used mainly in tests to break from the run().
- Parameters:
id – A fully qualified id of a service, i.e., also containing the node id.
- Returns:
None
- abstractmethod remove_pause_on_response(id: str) None
Removes an explicit interrupt to message processing, whenever a service sends a request.
- Parameters:
id – A fully qualified id of a service, i.e., also containing the node id.
- Returns:
None
- abstractmethod snapshot_save() str
Returns a complete state of the environment, from which it can be restored.
- Returns:
String representation of the environment
- abstractmethod snapshot_load(state: str) None
Attempts to restore the environment into the state described by the state string.
- Parameters:
state (str) – State representation obtained by snapshot_save function. Currently, the snapshots are not guaranteed to work across versions.
- Returns:
None
- abstractmethod transaction_start() Tuple[int, int, str]
Initiates a new transaction, which sets a point in time to which the environment can be reverted. The transaction has to begin as a first thing in a given time slot, i.e., if there was already a message processed in the time slot, the transaction will be set to start in the next time slot.
Multiple calls to transaction_start() at the same time slot start only one transaction.
Transactions can be interleaved. In case of a rollback, the state always returns to the beginning of transaction that was rolled back.
Transactions do not necessarily modify the state of active services, it is up to their authors, if they want to preserve, e.g., learned behavior across transactions.
- Returns:
A tuple containing transaction_id of started transaction, the time when the transaction starts, and additional information, if there is any.
- abstractmethod transaction_commit(transaction_id: int) Tuple[bool, str]
Finalizes a transaction. Such transaction is removed from the system and cannot be rolled back.
Any transaction can be committed by anyone. There is no validation of the caller.
- Parameters:
transaction_id (int) – The id of a transaction to commit.
- Returns:
A tuple indicating whether the transaction was successfully committed and providing additional information if present.
- abstractmethod transaction_rollback(transaction_id: int) Tuple[bool, str]
Returns the system into the state at the beginning of a transaction. After the transaction is rolled back, it is removed from the system.
Any transaction can be rolled back by anyone. There is no validation of a caller.
- Parameters:
transaction_id (int) – The ID of the transaction to roll back.
- Returns:
A tuple indicating whether a rollback was successful and providing additional information in present.
cyst.api.environment.external
This module enables accessing of resources outside the CYST environment in a manner that is conformant to the requirements of the internal processing and simulated/real time.
- class cyst.api.environment.external.ResourcePersistence(*values)
Bases:
EnumResources can be created in one of the two modes - transient and persistent. In the transient mode, they are opened and closed for each operation on them. In the persistent mode, they get opened on the first operation and must be closed via the
release_resource()function.- Possible values:
- TRANSIENT:
Open/close on each operation.
- PERSISTENT:
Stay opened after the first operation.
- class cyst.api.environment.external.Resource
Bases:
ABCResource interface represents an interface that is user-facing. A user does not interact with the resource directly, but is instead using the
ExternalResourcesinterface. Therefore, this interface provides only some minimal information about the resource.- abstract property path: str
The URL of the resource. Technically, many different resources can share the same URL and be differentiated just by the parameters that are provided with particular operations on the
ExternalResourcesinterface. Therefore, this property is only informative.
- abstract property persistence: ResourcePersistence
The persistence setting of the resource.
- class cyst.api.environment.external.ResourceImpl
Bases:
Resource,ABCThis interface represents an implementation of a resource that is used by the
ExternalResourceinterface. Any new or custom resources that are added to the system must inherit from bothResourceandResourceImpl.- abstractmethod init(path: ParseResult, params: dict[str, str] | None = None, persistence: ResourcePersistence = ResourcePersistence.TRANSIENT) bool
This function is called when the resource is initialized after being created.
- Parameters:
path (ParseResult) – The result of urllib.parse() call on the URL. The scheme is always guaranteed to be the same as the one used when this resource was registered.
params (Optional[dict[str, str]]) – Arbitrary parameters that may be required for resource initialization. If the resource is created implicitly via the ExternalResources interface, these parameters are shared with the call to
send()/receive().persistence (ResourcePersistence) – Persistence of a result. Implicitly created resources are always transient.
- Returns:
True if the resource was successfully created and False otherwise.
- abstractmethod open() None
This function is called prior to send/receive functions. It should prepare the resource for interactions.
- Returns:
None
- abstractmethod close() None
This function closes the resource. Any interaction after closing should fail. Close is either called immediately after
send()/receive()operation for transient resources, or called when the resource is released for persistent ones.- Returns:
None
- abstractmethod async send(data: str, params: dict[str, str] | None = None) int
This function sends the data to the resource, e.g., writes to the socket, writes to a file, or inserts into a database. Due to its async nature, you should utilize the async I/O operations, as the sync ones can disturb the execution of the rest of the processing.
- Parameters:
data (str) – The data that should be written.
params (Optional[dict[str, str]]) – Arbitrary parameters that modify the send operation. If the resource was implicitly created, these parameters may contain ones that are related to resource creation.
- Returns:
The number of characters that were actually written, even though the expectation here is that this function sends all the data or fails.
- abstractmethod async receive(params: dict[str, str] | None = None) str | None
This function read the data from the resource. Due to its async nature, you should utilize the async I/O operations, as the sync ones can disturb the execution of the rest of the processing.
- Parameters:
params (Optional[dict[str, str]]) – Arbitrary parameters that modify the receive operation. If the resource was implicitly created, these parameters may contain ones that are related to resource creation.
- Returns:
The data received from the resource or None if nothing was available or expected, e.g., HEAD HTTP request.
- class cyst.api.environment.external.ExternalResources
Bases:
ABCExternal resources represent any resources that are not part of the simulation/emulation runs, such as files, REST APIs, databases, etc. To maintain a sensible and consistent relation to underlying platforms and their time, all such resources must be handled through this interface.
Warning
Due to technical reasons related to dependence on an underlying platform, ExternalResources can be used only in the init/post-init state, including the attempts to register custom resources. That is, resources cannot be managed from the __init__ methods of behavioral models, platforms, or services.
- abstractmethod register_resource(scheme: str, resource: Type | ResourceImpl) bool
Register a given resource for given scheme.
- Parameters:
scheme (str) – URL scheme, i.e., the part before ://.
resource (Union[Type, ResourceImpl]) – The resource can either be provided as a type that implements the Resource and ResourceImpl interfaces, or it can be an object instance. If a type is provided then a new instance of the resource is created for each call of
create_resource(), including the implicit call in sending and fetching function. If a resource instance is provided then this resource acts as a singleton and multiple interleavedopen()andclose()calls can happen and the resource must be prepared to handle it gracefully.
- Returns:
True if the resource was successfully registered. False otherwise.
- abstractmethod create_resource(path: str, params: dict[str, str] | None = None, persistence: ResourcePersistence = ResourcePersistence.TRANSIENT) Resource
Creates an instance of a resource with a given path.
- Parameters:
path (str) – The URL of the resource. Full URL with scheme, e.g., file:// must be supplied to let system choose the correct one.
params (Optional[dict[str, str]]) – Arbitrary set of parameters that will be passed to the resource’s init function. If the resource is a singleton (cf.
register_resource()) then these parameters are ignored.persistence (ResourcePersistence) – The persistence of a resource. The
create_resource()function is usually called implicitly from the other functions, which set the persistence to transient. However, if you do not want the resource to be created and destroyed after each call, set the persistence to ResourcePersistence.PERSISTENT.
- Returns:
An instance of a resource. Otherwise, an exception is thrown.
- abstractmethod release_resource(resource: Resource) None
Releases a persistent resource. For a transient resource, this is a no-operation.
- Parameters:
resource (Resource) – An instance of a resource to close.
- Returns:
Nothing. This call always succeeds.
- abstractmethod async send_async(resource: str | Resource, data: str, params: dict[str, str] | None = None, timeout: float = 0.0) int
Asynchronously send data to a resource. This function is intended to be used by behavioral models and platforms. The agents currently must use the synchronous option.
- Parameters:
resource (Union[str, Resource]) – Either an instance of a resource, or its URL. When the URL is used, the resource is automatically created and destroyed within the call.
data (str) – Any data will be written to the resource. Technically, this can be empty and the contents can depend on the params.
params (Optional[dict[str, str]]) – Parameters for the sending operation. Such as choosing the write or append mode for the file resource.
timeout (float) – A maximum time given for the operation to finish. The semantic differs for simulated and emulated environments. For simulated ones, the timeout represents the actual length in virtual time units, whereas for emulated ones, the timeout is the maximum time to finish. That is, simulated send will always take timeout number of time units, and emulated will take up-to timeout time units.
- Returns:
The number of bytes written. However, the sending operation is expected to write all of its contents. In case of some error an exception should be thrown.
- abstractmethod send(resource: str | Resource, data: str, params: dict[str, str] | None = None, timeout: float = 0.0, callback_service: ActiveService | None = None) None
Synchronously send data to a resource. This function is expected to be used by agents, but it can be with a bit of over-engineering used by behavioral models and platforms as well. The main difference is that the results of the send operation are send inside a
MessageType.RESOURCEmessage.- Parameters:
resource (Union[str, Resource]) – Either an instance of a resource, or its URL. When the URL is used, the resource is automatically created and destroyed within the call.
data (str) – Any data will be written to the resource. Technically, this can be empty and the contents can depend on the params.
params (Optional[dict[str, str]]) – Parameters for the sending operation. Such as choosing the write or append mode for the file resource.
timeout (float) – A maximum time given for the operation to finish. The semantic differs for simulated and emulated environments. For simulated ones, the timeout represents the actual length in virtual time units, whereas for emulated ones, the timeout is the maximum time to finish. That is, simulated send will always take timeout number of time units, and emulated will take up-to timeout time units.
callback_service (Optional[ActiveService] = None) – A reference to an active service that will receive the result of the call within a resource message.
- Returns:
None. The sending operation is always expected to write all of its contents. In case of some error an exception is thrown.
- abstractmethod async fetch_async(resource: str | Resource, params: dict[str, str] | None = None, timeout: float = 0.0) str | None
Asynchronously reads data from a resource. This function is intended to be used by behavioral models and platforms. The agents currently must use the synchronous option.
- Parameters:
resource (Union[str, Resource]) – Either an instance of a resource, or its URL. When the URL is used, the resource is automatically created and destroyed within the call.
params (Optional[dict[str, str]]) – Parameters for the receiving operation.
timeout (float) – A maximum time given for the operation to finish. The semantic differs for simulated and emulated environments. For simulated ones, the timeout represents the actual length in virtual time units, whereas for emulated ones, the timeout is the maximum time to finish. That is, simulated send will always take timeout number of time units, and emulated will take up-to timeout time units.
- Returns:
The data read from the resource. It may return none and still be correct, such as the HEAD HTML request.
- abstractmethod fetch(resource: str | Resource, params: dict[str, str] | None = None, timeout: float = 0.0, callback_service: ActiveService | None = None) None
Synchronously reads data from a resource. This function is expected to be used by agents, but it can be with a bit of over-engineering used by behavioral models and platforms as well. The main difference is that the results of the fetch operation are send inside a
MessageType.RESOURCEmessage.- Parameters:
resource (Union[str, Resource]) – Either an instance of a resource, or its URL. When the URL is used, the resource is automatically created and destroyed within the call.
params (Optional[dict[str, str]]) – Parameters for the receiving operation.
timeout (float) – A maximum time given for the operation to finish. The semantic differs for simulated and emulated environments. For simulated ones, the timeout represents the actual length in virtual time units, whereas for emulated ones, the timeout is the maximum time to finish. That is, simulated send will always take timeout number of time units, and emulated will take up-to timeout time units.
callback_service (Optional[ActiveService] = None) – A reference to an active service that will receive the result of the call within a resource message.
- Returns:
The data read from the resource. It may return none and still be correct, such as the HEAD HTML request.
cyst.api.environment.infrastructure
- class cyst.api.environment.infrastructure.EnvironmentInfrastructure
Bases:
ABCThis interface provides access to environment resources that are aimed at behavioral models and to applications utilizing CYST.
- abstract property statistics: Statistics
Statistics track basic information about the simulation runs.
- Return type:
- abstract property data_store: DataStore
Data store provides access to storing run-related data for later analysis.
- Return type:
- abstract property service_store: ServiceStore
Provides access to creation and querying of active services.
- Return type:
- abstract property runtime_configuration: RuntimeConfiguration
Provides access to parameters that were set either through a command line or through environmental variables.
- Return type:
cyst.api.environment.interpreter
- class cyst.api.environment.interpreter.ActionInterpreter(*args, **kwargs)
Bases:
ABCAn action interpreter provides a semantic to the actions. It analyzes the incoming requests and then make appropriate changes in the environment and prepares responses that are sent back to the requests’ origin.
Deprecated since version 0.6.0: Replaced by behavioral models.
- class cyst.api.environment.interpreter.ActionInterpreterDescription(*args, **kwargs)
Bases:
objectA definition of an action interpreter.
- Parameters:
namespace (str) – A namespace in which all interpreted actions belong to. An arbitrary namespace nesting is supported through the dot notation (e.g., “a.b.c” namespaces and actions of the form “a.b.c.action_n”).
description (str) – A textual description of the action interpreter. The description should introduce the behavioral model that the interpreter implements, so that the users can decide whether to use it or not.
creation_fn (Callable[[EnvironmentConfiguration, EnvironmentResources, EnvironmentMessaging], ActionInterpreter]) – A factory function that can create the interpreter.
Deprecated since version 0.6.0: Replaced by behavioral models.
cyst.api.environment.message
- class cyst.api.environment.message.MessageType(*values)
Bases:
EnumThe type of the message.
Possible values:
- TIMEOUT:
The message is an information about expiration of a timeout.
- REQUEST:
The message is a request.
- RESPONSE:
The message is a response.
- RESOURCE:
The message carries a resource.
- SIGNAL:
The message is a signaling between the environment and components
- class cyst.api.environment.message.StatusOrigin(*values)
Bases:
EnumIndicates the origin of the status of the response.
Possible values:
- NETWORK:
The original request was processed and evaluated at the network or router level.
- NODE:
The original request was processed and evaluated at the node level, without reaching a specific service.
- SERVICE:
The original request was processed and evaluated at the service level.
- RESOURCE:
The original request was for the resources.
- SYSTEM:
The original request couldn’t be evaluated in the environment context. This indicates a system error.
- class cyst.api.environment.message.StatusValue(*values)
Bases:
EnumIndicates the general result of the response.
Possible values:
- SUCCESS:
The action intended in the original request was successfully carried out.
- FAILURE:
The action intended in the original request was not successful due to wrong parameter combination or values.
- ERROR:
The action intended in the original request was not successful because of missing parameters or because the action could not be evaluated.
- PARTIAL:
The action intended in the original request was partially successful and another response should be expected to arrive soon.
- class cyst.api.environment.message.StatusDetail(*args, **kwargs)
Bases:
FlagsStatus detail provides another introspection mechanism to active services into the nature of failures and errors. Status detail follows unified naming convention WHAT_WHY, where WHY is one of the following:
NOT_PROVIDED: WHAT was not passed as a parameter, even though it is required
NOT_EXISTING: WHAT does not exist within the context of current simulation run (e.g., service name, user name, etc.)
NOT_APPLICABLE: WHAT cannot be used (e.g., wrong authorization, wrong exploit parameters, etc.)
NOT_SUPPORTED: WHAT exists as a valid concept, but the target does not support it (e.g., attempting to open a session to a service that does not support it)
NEXT: WHAT was a correct step towards success, but another WHAT is required
- General:
- UNKNOWN:
There is no additional detail to be provided.
- NODE.FAILURE:
- PRIVILEGES_NOT_APPLICABLE:
A wrong authentication/authorization used.
- NODE.ERROR:
- SERVICE_NOT_PROVIDED:
No service was specified.
- SERVICE_NOT_EXISTING:
A service does not exist at the node.
- SESSION_NOT_PROVIDED:
A session was required but not provided.
- SESSION_NOT_APPLICABLE:
A wrong session was provided.
- SERVICE.FAILURE:
- SESSION_CREATION_NOT_SUPPORTED:
A session cannot be created with this service.
- EXPLOIT_NOT_PROVIDED:
An action required an exploit, but it was not provided.
- EXPLOIT_NOT_APPLICABLE:
An exploit could not be used in combination with an action to affect the service.
- EXPLOIT_CATEGORY_NOT_APPLICABLE:
Wrong exploit category was used (e.g., data manipulation exploit for privilege escalation)
- EXPLOIT_LOCALITY_NOT_APPLICABLE:
Wrong exploit locality was used (e.g., local exploit for remote action)
- EXPLOIT_PARAMETER_NOT_PROVIDED:
A required exploit parameter was missing.
- EXPLOIT_PARAMETER_NOT_APPLICABLE:
A provided parameter in exploit could not be used to affect the service.
- AUTHORIZATION_NOT_PROVIDED:
An authorization was missing when trying to access the service.
- AUTHORIZATION_NOT_APPLICABLE:
A wrong authorization was used to access the service.
- AUTHENTICATION_NOT_PROVIDED:
An authentication token was missing when trying to authenticate against the service.
- AUTHENTICATION_NOT_APPLICABLE:
A wrong authentication token was used when trying to authenticate against the service.
- AUTHENTICATION_NEXT:
A previous step in multi-factor authentication step was successful, another step must be undertaken.
- SYSTEM.ERROR:
- ACTION_NOT_EXISTING:
There is no interpreter able to interpret the given action.
- class cyst.api.environment.message.Status(origin: ~cyst.api.environment.message.StatusOrigin, value: ~cyst.api.environment.message.StatusValue, detail: ~cyst.api.environment.message.StatusDetail = <StatusDetail.UNKNOWN bits=0x0001 data=UNDEFINED>)
Bases:
objectStatus is bound to responses, as it informs about the result of request processing.
- Parameters:
origin (StatusOrigin) – The origin of the status.
value (StatusValue) – The value of the status.
detail (StatusDetail) – Additional specification of the status value.
- class cyst.api.environment.message.Message
Bases:
ABCMessage provides a mean to exchange information between elements of the simulation.
- abstract property id: int
A numerical identifier of the message, which is unique across a simulation run. The request and response share the same id to enable correct pairing.
- Return type:
int
- abstract property type: MessageType
A type of the message.
- Return type:
- abstract property src_ip: IPAddress | None
An IP address from which the message was sent. Messages not yet sent and timeouts do not have a source IP.
- Return type:
Optional[IPAddress]
- abstract property dst_ip: IPAddress | None
An IP address where the message was sent to. Timeouts do not have a destination IP.
- Return type:
Optional[IPAddress]
- abstract property src_service: str | None
A service that produced the message. In case of service-less origins, such as router processing, the service is empty.
- Return type:
Optional[str]
- abstract property dst_service: str
A service that is the ultimate target for the message.
- Return type:
str
- abstract property auth: Authorization | AuthenticationToken | AuthenticationTarget | None
An authentication/authorization associated with the message. In case of requests, it can either contain Authorizations or Authentication tokens provided by the origin. In case of responses, it can be the original Authorization provided by the origin, Authorization provided by the destination service as a result of an actions, or Authentication target if the request was a part of multi-factor authentication scheme message exchange.
- Return type:
Optional[Union[Authorization, AuthenticationToken, AuthenticationTarget]]
- abstract property ttl: int
Time-to-live of the message. After each pass through a router, this value gets decreased and the message gets discarded if it ever reaches 0. This mechanism exists to prevent endless resending of a message in case of bad network topology.
- Return type:
int
- abstract property metadata: Metadata
Metadata associated with the message. The metadata is supplied to the message by metadata providers (see
cyst.api.environment.metadata_provider.MetadataProvider). The metadata mechanism is intended to provide at least some information for active services, who are not able to see the action portion of a message (at least that is the plan, currently they can).- Return type:
- abstractmethod set_metadata(metadata: Metadata) None
Sets a metadata to the message. This call overwrites the original value, so, if there is a multitude of metadata providers, it is advisable to use
add_metadata().- Parameters:
metadata – A new value of the metadata.
- abstract property platform_specific: Dict[str, Any]
Provides access to platform-specific parameters of a message. Their contents can be arbitrary and are intended for assisting with message handling in a non CYST-simulated environments.
- Return type:
Dict[str, Any]
Added in version 0.6.0.
- abstractmethod cast_to(type: Type[T]) T
This function enables typecasting of Message into one of the four derived types: Request, Response, Resource, and Timeout. While technically not necessary due to Python’s type system, it conveys intention and also makes a check whether the conversion can actually be done.
- Parameters:
type (Type[TypeVar('T', bound=Union['Request', 'Response', 'Resource', 'Timeout'])]) – A type to cast the mesasge to.
- Return type:
T
- class cyst.api.environment.message.Request
Bases:
Message,ABCRequest is a message specialization that carries an action.
- class cyst.api.environment.message.Response
Bases:
Message,ABCResponse is a message specialization the carries the result of associated request.
- abstract property action: Action
Gets an action associated with the original request.
- Return type:
Added in version 0.6.0.
- abstract property content: Any | None
Any associated information that was included during the processing of the associated request.
- Return type:
Optional[Any]
- class cyst.api.environment.message.Timeout
Bases:
Message,ABCTimeout is a message specialization that is delivered when a timeout requested through the
cyst.api.environment.clock.Clockinterface.- abstract property start_time: float
A simulation time when the timeout was requested.
- Return type:
int
- abstract property duration: float
A duration of the timeout in simulated time units.
- Return type:
int
- abstract property parameter: Any
Any parameter that was included during the invocation of the timeout function.
- Return type:
Any
- class cyst.api.environment.message.Resource
Bases:
Message,ABCResource is a message specialization that is delivered when an asynchronous external resource was requested.
- abstract property path: str
A URL of the resource.
- Rtype str:
- abstract property data: str | None
Data retrieved from the external resource. In case the system failed to extract the data (due to timeout or error), the return is set to None.
- Return type:
Optional[str]
- class cyst.api.environment.message.ComponentState(*args, **kwargs)
Bases:
FlagsComponent state represents an abstract state of a particular component within simulation. The state is expressed as a flag, so, multiple states can be expressed at once.
- States related to the component lifetime:
- CREATED:
A component was just created.
- INIT:
A component was successfully initialized.
- RUNNING:
A component is running in a nominal fashion.
- PAUSED:
An execution of component’s functions was paused.
- STOPPED:
An execution of component’s functions was stopped.
- FINISHED:
A component stopped its operation in a normal way.
- TERMINATED:
A component stopped its operation through some external factor.
- States related to action effects:
- UNDER_ATTACK:
A component is a subject to hostile activity. Note that there is no state indicating that attack has ended.
- UNDER_CONTROL:
A component was subject to hostile activity that resulted in access or control from the origin of activity.
- RESTORED:
A component is no longer UNDER_CONTROL.
- DETECTED:
A component was marked as doing malicious activities.
- BLOCKED:
A component was blocked by a prevention system.
- UNBLOCKED:
A component is no longer blocked.
- States related to goal pursuit:
- GOAL_REACHED:
A component reached its stated goal.
- GOAL_UNREACHABLE:
A component is unable to reach its goal.
- States related to the iteration or repeated state occurrence:
- FIRST_OCCURRENCE:
The state appeared for the first time (can also be the first occurRence after some major change)
- REPEATED_OCCURRENCE:
The state apeeared multiple times (details can be provided by Signal.effect_parameters)
An example of a state evolution of a service under a successful attack:
ComponentState.UNDER_ATTACK ComponentState.UNDER_CONTROL ComponentState.TERMINATED
An example of a state evolution of a service that was attacked and cleaned afterward:
ComponentState.UNDER_ATTACK ComponentState.UNDER_CONTROL ComponentState.STOPPED ComponentState.RUNNING | ComponentState.RESTORED
An example of a attacker being detected and blocked (the state is reported by IPS, not the agent):
ComponentState.DETECTED ComponentState.BLOCKED | ComponentState.FIRST_OCCURRENCE … attacker continues with attack ComponentState.BLOCKED | ComponentState.REPEATED_OCCURRENCE … attacker stops with an attack ComponentState.UNBLOCKED … attacker attacks again ComponentState.BLOCKED | ComponentState.FIRST_OCCURRENCE
An attacker signalling that it reached its goal and do not wish to continue the run:
ComponentState.FINISHED | ComponentState.GOAL_REACHED
- class cyst.api.environment.message.Signal
Bases:
Message,ABCSignal is a message specialization that is used for communicating state changes between the environment and simulation components.
- abstract property signal_origin: str
An identification of a source of the signal. This will usually be the ID of a component, or “__environment” if the signal is coming from within CYST.
- Return type:
str
- abstract property state: ComponentState
A new state that the component entered.
- Return type:
- abstract property effect_origin: str
An identification of a source of the state change that prompted the signal emission.
- Return type:
str
- abstract property effect_message: int | None
An ID of a message that caused the state change. In case of environment signals, there does not have to be any related message (such as the environment termination).
- Return type:
Optional[int]
- abstract property effect_description: str
A description of an effect used mainly for later analysis. For example “Maximum number of actions reached”, or “Successful execution of an action x:y”. This is not expected to be machine-processable .
- Return type:
str
- abstract property effect_parameters: Dict[str, Any]
Additional information related to the state change. For example, an agent may use this to signal its perceived reward, or some important training/execution parameters.
- Return type:
Dict[str, Any]
cyst.api.environment.messaging
- class cyst.api.environment.messaging.EnvironmentMessaging
Bases:
ABCThis interface enables creating and sending of messages within simulation.
- abstractmethod send_message(message: Message, delay: float = 0.0) None
Sends a message into the simulation for processing. The system will attempt to route the message to its destination. If there is a problem with delivery, an indication of it will be received in form of another message. This call always succeeds.
- Parameters:
message (Message) – The message to be sent.
delay (float) – Simulation time delay between calling of this function and the actual dispatching of the message into the simulated infrastructure.
- Returns:
None
- abstractmethod create_request(dst_ip: str | IPAddress, dst_service: str = '', action: Action | None = None, session: Session | None = None, auth: Authorization | AuthenticationToken | None = None, original_request: Request | None = None) Request
Creates a message of type REQUEST. This function is a domain of active services.
- Parameters:
dst_ip (Union[str, IPAddress]) – A destination IP address. If provided in the string form, it will attempt to convert it internally into the IPAddress.
dst_service (str) – The name of the service this message should be routed to.
action (Action) – An action that should be performed at the destination. Even though this function technically enables action-less message, it is an implementation detail and such message would be dropped at the first hop. TODO: Check it.
session (Session) – An optional session to use for a routing of this message.
auth (Union[Authorization, AuthenticationToken]) – Either authentication or authorization token to use for this message. If an authentication token is provided and the type of action is _not_ meta:authenticate, then the system will internally attempt to obtain an authorization by means of the meta:authenticate action and the proceed with the original action. More in the description of the authentication/authorization framework.
original_request (Request) – If provided, values from the original request are used to fill blanks in the new request. This is seldom needed in agent’s code and is more useful when creating behavioral models.
- Returns:
A Request to be sent.
Changed in version 0.6.0: Added original request parameter to enable request copying
- abstractmethod create_response(request: Request, status: Status, content: Any | None = None, session: Session | None = None, auth: Authorization | AuthenticationTarget | None = None, original_response: Response | None = None) Response
Creates a message of type RESPONSE. This response is always created from a request.
- Parameters:
request (Request) – The request to which this response is created.
status (Status) – A status code of the response.
content (Optional[Any]) – A message body. Currently anything can be sent in the response, but it is expected that in future updates, the content will have its taxonomy and domains, so that automated reasoning can be fully applied to message processing.
session (Session) – Either the original session that is inherited from the request, or a new session that is created as a part of request processing. If the request arrived through a session, a session must be present with the response. Otherwise, the message would not be correctly routed.
auth (Optional[Union[Authorization, AuthenticationTarget]]) – By convention, this parameter should be the original request’s authorization token, unless the request resulted in a creation of a new authorization token, or unless the request-response is a part of a multi-factor authentication (in which case an Authenticationtarget is returned).
original_response (Response) – If provided, values from the original response are used to fill blanks in the new request. This is seldom needed in agent’s code and is more useful when creating behavioral models.
- Returns:
A response to be sent.
Changed in version 0.6.0: Added original response parameter to enable response copying
- abstractmethod create_signal(signal_origin: str, state: ComponentState, effect_origin: str, effect_message: int | None = None, effect_description: str = '', effect_parameters: Dict[str, Any] | None = None) Signal
Creates a message of type SIGNAL.
- Parameters:
signal_origin (str) – An identification of a source of the signal. Usually an ID of your component.
state (ComponentState) – A new state that the component entered.
effect_origin (str) – An identification of a source of the state change that prompted the signal emission.
effect_message (Optional[int]) – An ID of a message that caused the state change.
effect_description (str) – A description of an effect used mainly for later analysis.
effect_parameters (Optional[Dict[str, Any]]) – Additional information related to the state change.
Added in version 0.6.0.
- abstractmethod open_session(request: Request, reverse_direction: bool = False) Session
Opens a session to the source of the request. If the request already contains a session, it will append the session, unless the current node is an endpoint of that session. In that case, the same session is returned.
- Parameters:
request (Request) – The request from which the session is established.
reverse_direction (bool) – Whether the direction of the shell is reversed or not.
- Returns:
A session to the request source.
cyst.api.environment.metadata_provider
- class cyst.api.environment.metadata_provider.MetadataProvider
Bases:
ABCMetadata providers supply messages with additional information that are meant to mimic observations that can be done in the real life. Two typical examples of metadata can be 1) flow information, 2) results of traffic analyses.
- abstractmethod get_metadata(action: Action, message: Message) Metadata
This function should return metadata that correspond to the given message.
- Parameters:
action (Action) – The action for which the metadata should be provided. Given that a message can carry multiple actions, a metadata provider must adhere to this parameter and not try to extract it from the message itself.
message (Message) – An instance of the message. The message should be used to provide additional information necessary to supply correct metadata, such as message type, message status, etc.
- Returns:
A metadata associated with the message.
Changed in version 0.6.0: Metadata are collected for a whole message at the time of sending and are no longer solely dependent on Action.
- class cyst.api.environment.metadata_provider.MetadataProviderDescription(namespace: str, description: str, creation_fn: Callable[[], MetadataProvider])
Bases:
objectA description of a metadata provider which should be registered into the system.
- Parameters:
namespace (str) – A namespace of actions that this provider works with.
description (str) – A short description of the provider.
creation_fn (Callable[[ActionStore, ActionConfiguration], MetadataProvider]) – A factory function that creates instances of the metadata provider.
cyst.api.environment.platform
- class cyst.api.environment.platform.Platform
Bases:
ABCPlatform interface provides an abstraction layer for different execution environments, e.g., simulation or emulation. When creating a new Environment a platform is instantiated and from then it takes care of message delivery and infrastructure configuration. As such, it is closely related to behavioral models, whose actions are custom tailored for a given platform.
- abstractmethod init() bool
Initialize platform. After this call, the platform should correctly process all calls. The platform need not check whether the init was called, the core will execute it exactly once before calling anything else.
If the initialization was not successful, the platform should shutdown gracefully and release all resources. Error should be communicated via the logging interface.
- Returns:
True if the initialization finished successfully. False otherwise.
- abstractmethod terminate() bool
Terminate all platform operations. Within this call, all messages should be disposed of and the configured infrastructure should be torn down. This function will be called only once, so there is no need for checking.
If the termination was not successful, the platform should shutdown as much as possible and indicate problems via the logging interface.
- Returns:
True if the termination finished successfully. False otherwise.
- abstract property configuration: EnvironmentConfiguration
The configuration interface for the entire platform. In essence, platforms may implement up-to the extent of CYST simulation. But it is generally understood that the configuration options for, e.g., emulation platforms will be much more limited and will not enable all on-the-fly modifications.
Thus, platforms has to implement (and really implement because of usage of abstract base classes), the following:
NodeConfiguration: every method can end with exception
NetworkConfiguration: every method can end with exception
AccessConfiguration: every method can end with exception
ServiceConfiguration:
get_service_interface()must be implemented, the rest can end with exceptionActionConfiguration: the one provided by the core can be used
ExploitConfiguration: the one provided by the core can be used
GeneralConfiguration:
get_configuration(),save_configuration(),load_configuration(), andget_configuration_by_id()should be proxied back to the core.get_object_by_id()must be implemented.
- Returns:
An environment configuration interface.
- abstractmethod configure(*config_item: ConfigItem) Platform
Configures the platform, according to provided configuration items. This function can be called repeatedly, however, each subsequent should replace the previous configuration. Therefore, a configuration must be done at once and every later change in the environment setup must be done through the
cyst.api.environment.configuration.EnvironmentConfigurationinterface.- Parameters:
config_item (ConfigItem) – One or more configuration items. The number of items can be arbitrary and it is not order-dependent.
- Returns:
The configured platform.
- abstract property messaging: EnvironmentMessaging
Provides access to messaging within the platform. Considering the variable nature of different platforms, they are expected to supply their own implementation of different messages (
cyst.api.environment.message.Message,cyst.api.environment.message.Request,cyst.api.environment.message.Response,cyst.api.environment.message.Timeout). They do not have to implementcyst.api.environment.message.Resource, as this is a domain of the core.- Returns:
An environment messaging interface.
- abstractmethod async process(time_advance: float) bool
The main processing loop of the platform. Within this loop, the platform should process all messages that were enqueued through the
cyst.api.environment.messaging.EnvironmentMessaginginterface.- Parameters:
time_advance (float) – A hint to advance the time by the specified amount of time units. The platform is free to ignore the parameter in real-time based systems. In simulated systems, where the time is under the control of the platform the time should be advanced to prevent a deadlock.
- Returns:
True if there was a message to process, False otherwise.
- class cyst.api.environment.platform.PlatformDescription(specification: PlatformSpecification, description: str, creation_fn: Callable[[PlatformInterface, GeneralConfiguration, EnvironmentResources, ActionConfiguration, ExploitConfiguration, PhysicalConfiguration, EnvironmentInfrastructure], Platform])
Bases:
objectA description of a platform that is loaded as a module to CYST.
- Parameters:
specification (PlatformSpecification) – A platform specification that has to be unique among all loaded modules.
description (str) – A textual description of the platform and its capabilities. A user-facing string.
creation_fn (Callable[[PlatformInterface, GeneralConfiguration, EnvironmentResources, ActionConfiguration, ExploitConfiguration, EnvironmentInfrastructure], Platform]) – A platform instantiation function.
cyst.api.environment.platform_interface
- class cyst.api.environment.platform_interface.PlatformInterface
Bases:
ABCAn interface that enables platforms to communicate with the core to elicit effects.
- abstractmethod execute_task(task: Message, service: Service | None = None, node: Node | None = None, delay: float = 0.0) Tuple[bool, float]
Instruct the core to execute included action with the appropriate behavioral model. The function signature follows the signature of
cyst.api.logic.behavioral_model.action_effect().- Parameters:
task (Message) – The message containing the action. In virtually all cases this will be messages of type
MessageType.REQUEST, however, there is nothing preventing a platform to call behavioral models for actions on responses.service (Optional[Service]) – A service on which the action should be executed. The platform is free to ignore this parameter if its associated behavioral model does not require it.
node (Optional[Node]) – A node on which the action should be executed. The platform is free to ignore this parameter if its associated behavioral model does not require it.
delay (float) – A delay before the execution of the action.
- Returns:
A tuple indicating whether the action was successfully executed and how long the execution took.
cyst.api.environment.platform_specification
- class cyst.api.environment.platform_specification.PlatformType(*values)
Bases:
EnumDifferentiates the modus operandi of the platform. As there is a blurry line between the simulation and emulation, we differentiate them in respect their control of time.
Possible values:
- SIMULATED_TIME:
A platform fully controls execution time.
- REAL_TIME:
A platform is operating in real-time.
- class cyst.api.environment.platform_specification.PlatformSpecification(type: PlatformType, provider: str)
Bases:
objectA specification of a platform. Each specification must be unique among the loaded modules.
- Parameters:
type (PlatformType) – Type of execution of the platform.
provider (str) – A unique identifier of the platform. This string is used by the users to select the platform in the call to Environment’s
create()method.
cyst.api.environment.policy
cyst.api.environment.resources
- class cyst.api.environment.resources.EnvironmentResources
Bases:
ABCThis interface provides access to resources that can be used by services within the simulation.
- abstract property action_store: ActionStore
Through action store, services access actions that are available to them in the simulation.
- Return type:
- abstract property exploit_store: ExploitStore
Through exploit store, services access exploits that can be tied to actions.
- Return type:
- abstract property clock: Clock
Clock provides a mean to track simulation and hybrid time.
- Return type:
- abstract property external: ExternalResources
External resources enable to interface simulation with data and services outside.
- Return type:
cyst.api.environment.stats
- class cyst.api.environment.stats.Statistics
Bases:
ABCStatistics class tracks various statistical information about simulation runs.
- abstract property run_id: str
Get the ID of the current run
- Return type:
str
- abstract property configuration_id: str
Get the ID of the configuration that is stored in the data store and that was used for the current run.
- Return type:
str
- abstract property start_time_real: float
Get the wall clock time when the current run started. The time is in the python time() format.
- Return type:
float
- abstract property end_time_real: float
Get the wall clock time when the current run was commited. The time is in the python time() format.
- Return type:
float
- abstract property end_time_virtual: int
Get the virtual time of the current run, i.e., the number of ticks. As the run always starts at 0, this function represents also the run duration.
- Return type:
int
cyst.api.environment.stores
- class cyst.api.environment.stores.ActionStore
Bases:
ABCAction store provides access to actions that are available to services.
- abstractmethod get(id: str = '') Action | None
Returns an action with given ID. This function makes a copy of the object, which is present in the store. This is a preferred variant, because any parameters set on that action would propagate to the store.
- Parameters:
id (str) – A unique ID of the action.
- Returns:
An action, if there is one with such ID and for such execution environment.
- abstractmethod get_ref(id: str = '') Action | None
Return an action with give ID. This function returns a reference to the object stored in the store and any parameter alterations will propagate to all subsequent queries for this action.
- Parameters:
id (str) – A unique ID of the action.
- Returns:
An action, if there is one with such ID and for such execution environment.
- abstractmethod get_prefixed(prefix: str = '') List[Action]
Gets a list of actions, whose ID starts with a given string. This is usually done to get access to the entire namespace of a particular behavioral model.
The list will contain copies of actions present in the store. Getting multiple references in one call is not supported.
- Parameters:
prefix (str) – The prefix all actions IDs must share.
- Returns:
A list of actions with the same prefix.
- abstractmethod add(action: ActionDescription) None
Adds a new action to the store. This function should be used in two cases:
Adding new action for a behavioral model. Such action must have a processing function mapped to the action ID.
Adding new action for intra-agent communication. There is no requirement on the action form, however an exception will be thrown, if this action is directed to a passive service, as the system will have no idea how to process it.
- Parameters:
action (ActionDescription) – A description of the action to add.
- Returns:
None
- class cyst.api.environment.stores.ExploitStore
Bases:
ABCExploit store provides access to exploits that can be used together with actions. Unlike the action store, runtime definition of exploits by services is not permitted. This must be done through the
cyst.api.environment.configuration.ExploitConfigurationinterface.- abstractmethod get_exploit(id: str = '', service: str = '', category: ExploitCategory = ExploitCategory.NONE) List[Exploit] | None
Gets an exploit, which satisfy all the parameters.
- Parameters:
id (str) – An explicit ID of an exploit.
service (str) – An ID of a service the exploit can be used at.
category (ExploitCategory) – A category that the exploit should have. If the ExploitCategory.NONE is set, then the category is not considered when retrieving the exploits.
- Returns:
A list of exploits satisfying the parameters.
- abstractmethod evaluate_exploit(exploit: str | Exploit, message: Message, node: Node) Tuple[bool, str]
Evaluates, whether the provided exploit is applicable, given the message which carries the relevant action and a concrete node. TODO: This interface is cumbersome. While this is best fit for the data that interpreters receive, it is confusing at best.
- Parameters:
- Returns:
(True, _) if exploit is applicable, (False, reason) otherwise.
- class cyst.api.environment.stores.ServiceStore
Bases:
ABCService store provides a unified interface for creating active services. Due to centrality of this concept to all CYST, regardless of the platform it uses, all services must be instantiated through this store.
Added in version 0.6.0.
- abstractmethod create_active_service(type: str, owner: str, name: str, node: Node, service_access_level: AccessLevel = AccessLevel.LIMITED, configuration: Dict[str, Any] | None = None, id: str = '') ActiveService | None
Creates an active service instance.
- Parameters:
type – The name of the active service, under which it is registered into the system.
owner – The identity of user, under whose identity this service should be running.
name – The name of the service, under which it is present at the node. Currently, it is used instead of ports to route messages. TODO: The name/id system is retarded and has to be changed.
node – The node at which the service should be instantiated.
service_access_level – The level of access the service has on the system.
id – System-wide unique ID of the service. Unless overridden, it will have the form of <node_id>.<service_name>.
configuration – A dictionary with arbitrary configuration items.
- Returns:
The instantiated active service or None if there was an error.
- abstractmethod get_active_service(id) ActiveService | None
Returns an already instantiated active service, given its full id (that is, not just a name).
- Parameters:
id
- Returns:
- class cyst.api.environment.stores.DataStore
Bases:
ABCAdded in version 0.6.0.
- abstractmethod add_action(*action: ActionModel) None
Store information about a resolved action, i.e., after completing the request-response cycle.
- Parameters:
action – An action(s) description
- Returns:
None
- abstractmethod add_message(*message: Message) None
Store information about a message. While in general, the message information is available only at the point of dispatching the message, platforms that have more control over the message passing process (e.g., simulation platform of CYST) may report the same message multiple times during the message passing. Additional information shall then be passed through the .platform_specific attributed, which gets erased before entering user-facing side of the code.
- Parameters:
message – The message(s) to store
- Returns:
None
- abstractmethod add_statistics(statistics: Statistics) None
Store statistics related to one run.
- Parameters:
statistics – The statistics to store.
- Returns:
None
- class cyst.api.environment.stores.DataStoreDescription(backend: str, description: str, creation_fn: Callable[[str, Dict[str, str]], DataStore])
Bases:
objectEntry point for an implementation of a data store backend.
- Parameters:
backend (str) – The name of the backend the data store uses. This name has to be unique within the system.
description (str) – A textual description of the data store backend.
creation_fn (Callable[[str, Dict[str, str]], DataStore]) – A factory function that can create the data store backend. Its parameters are the run_id and backend-specific key-value pairs.
Added in version 0.6.0.