#3062 - First pass at unifying naming convention for discriminators (still errors) [skip ci]

This commit is contained in:
Marek Wolan
2025-02-03 16:24:03 +00:00
parent 055c853b0f
commit abccf4afc5
195 changed files with 2824 additions and 2802 deletions

View File

@@ -24,7 +24,7 @@ game:
agents:
- ref: client_2_green_user
team: GREEN
type: ProbabilisticAgent
type: probabilistic-agent
agent_settings:
action_probabilities:
0: 0.3
@@ -34,33 +34,33 @@ agents:
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_application_execute
action: node-application-execute
options:
node_name: client_2
application_name: WebBrowser
application_name: web-browser
2:
action: node_application_execute
action: node-application-execute
options:
node_name: client_2
application_name: DatabaseClient
application_name: database-client
reward_function:
reward_components:
- type: WEBPAGE_UNAVAILABLE_PENALTY
- type: webpage-unavailable-penalty
weight: 0.25
options:
node_hostname: client_2
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
- type: green-admin-database-unreachable-penalty
weight: 0.05
options:
node_hostname: client_2
- ref: client_1_green_user
team: GREEN
type: ProbabilisticAgent
type: probabilistic-agent
agent_settings:
action_probabilities:
0: 0.3
@@ -70,26 +70,26 @@ agents:
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_application_execute
action: node-application-execute
options:
node_name: client_1
application_name: WebBrowser
application_name: web-browser
2:
action: node_application_execute
action: node-application-execute
options:
node_name: client_1
application_name: WebBrowser
application_name: web-browser
reward_function:
reward_components:
- type: WEBPAGE_UNAVAILABLE_PENALTY
- type: webpage-unavailable-penalty
weight: 0.25
options:
node_hostname: client_1
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
- type: green-admin-database-unreachable-penalty
weight: 0.05
options:
node_hostname: client_1
@@ -100,31 +100,31 @@ agents:
- ref: data_manipulation_attacker
team: RED
type: RedDatabaseCorruptingAgent
type: red-database-corrupting-agent
agent_settings:
possible_start_nodes: [client_1, client_2]
target_application: DataManipulationBot
target_application: data-manipulation-bot
start_step: 25
frequency: 20
variance: 5
- ref: defender
team: BLUE
type: ProxyAgent
type: proxy-agent
observation_space:
type: CUSTOM
type: custom
options:
components:
- type: NODES
- type: nodes
label: NODES
options:
hosts:
- hostname: domain_controller
- hostname: web_server
services:
- service_name: WebServer
- service_name: web-server
- hostname: database_server
folders:
- folder_name: database
@@ -169,7 +169,7 @@ agents:
- UDP
num_rules: 10
- type: LINKS
- type: links
label: LINKS
options:
link_references:
@@ -183,222 +183,222 @@ agents:
- switch_2:eth-1<->client_1:eth-1
- switch_2:eth-2<->client_2:eth-1
- switch_2:eth-7<->security_suite:eth-2
- type: "NONE"
- type: "none"
label: ICS
options: {}
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
# scan webapp service
1:
action: node_service_scan
action: node-service-scan
options:
node_name: web_server
service_name: WebServer
service_name: web-server
# stop webapp service
2:
action: node_service_stop
action: node-service-stop
options:
node_name: web_server
service_name: WebServer
service_name: web-server
# start webapp service
3:
action: "node_service_start"
action: "node-service-start"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
4:
action: "node_service_pause"
action: "node-service-pause"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
5:
action: "node_service_resume"
action: "node-service-resume"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
6:
action: "node_service_restart"
action: "node-service-restart"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
7:
action: "node_service_disable"
action: "node-service-disable"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
8:
action: "node_service_enable"
action: "node-service-enable"
options:
node_name: web_server
service_name: WebServer
service_name: web-server
9: # check database.db file
action: "node_file_scan"
action: "node-file-scan"
options:
node_name: database_server
folder_name: database
file_name: database.db
10:
action: "node_file_scan" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
action: "node-file-scan" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
options:
node_name: database_server
folder_name: database
file_name: database.db
11:
action: "node_file_delete"
action: "node-file-delete"
options:
node_name: database_server
folder_name: database
file_name: database.db
12:
action: "node_file_repair"
action: "node-file-repair"
options:
node_name: database_server
folder_name: database
file_name: database.db
13:
action: "node_service_fix"
action: "node-service-fix"
options:
node_name: database_server
service_name: DatabaseService
service_name: database-service
14:
action: "node_folder_scan"
action: "node-folder-scan"
options:
node_name: database_server
folder_name: database
15:
action: "node_folder_scan" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
action: "node-folder-scan" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
options:
node_name: database_server
folder_name: database
16:
action: "node_folder_repair"
action: "node-folder-repair"
options:
node_name: database_server
folder_name: database
17:
action: "node_folder_restore"
action: "node-folder-restore"
options:
node_name: database_server
folder_name: database
18:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: domain_controller
19:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: domain_controller
20:
action: node_startup
action: node-startup
options:
node_name: domain_controller
21:
action: node_reset
action: node-reset
options:
node_name: domain_controller
22:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: web_server
23:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: web_server
24:
action: node_startup
action: node-startup
options:
node_name: web_server
25:
action: node_reset
action: node-reset
options:
node_name: web_server
26: # old action num: 18
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: database_server
27:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: database_server
28:
action: node_startup
action: node-startup
options:
node_name: database_server
29:
action: node_reset
action: node-reset
options:
node_name: database_server
30:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: backup_server
31:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: backup_server
32:
action: node_startup
action: node-startup
options:
node_name: backup_server
33:
action: node_reset
action: node-reset
options:
node_name: backup_server
34:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: security_suite
35:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: security_suite
36:
action: node_startup
action: node-startup
options:
node_name: security_suite
37:
action: node_reset
action: node-reset
options:
node_name: security_suite
38:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: client_1
39: # old action num: 19 # shutdown client 1
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: client_1
40: # old action num: 20
action: node_startup
action: node-startup
options:
node_name: client_1
41: # old action num: 21
action: node_reset
action: node-reset
options:
node_name: client_1
42:
action: "node_os_scan"
action: "node-os-scan"
options:
node_name: client_2
43:
action: "node_shutdown"
action: "node-shutdown"
options:
node_name: client_2
44:
action: node_startup
action: node-startup
options:
node_name: client_2
45:
action: node_reset
action: node-reset
options:
node_name: client_2
46: # old action num: 22 # "ACL: ADDRULE - Block outgoing traffic from client 1"
action: "router_acl_add_rule"
46: # old action num: 22 # "acl: ADDRULE - Block outgoing traffic from client 1"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 1
@@ -410,8 +410,8 @@ agents:
protocol_name: ALL
src_wildcard: NONE
dst_wildcard: NONE
47: # old action num: 23 # "ACL: ADDRULE - Block outgoing traffic from client 2"
action: "router_acl_add_rule"
47: # old action num: 23 # "acl: ADDRULE - Block outgoing traffic from client 2"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 2
@@ -424,7 +424,7 @@ agents:
src_wildcard: NONE
dst_wildcard: NONE
48: # old action num: 24 # block tcp traffic from client 1 to web app
action: "router_acl_add_rule"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 3
@@ -437,7 +437,7 @@ agents:
src_wildcard: NONE
dst_wildcard: NONE
49: # old action num: 25 # block tcp traffic from client 2 to web app
action: "router_acl_add_rule"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 4
@@ -450,7 +450,7 @@ agents:
src_wildcard: NONE
dst_wildcard: NONE
50: # old action num: 26
action: "router_acl_add_rule"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 5
@@ -463,7 +463,7 @@ agents:
src_wildcard: NONE
dst_wildcard: NONE
51: # old action num: 27
action: "router_acl_add_rule"
action: "router-acl-add-rule"
options:
target_router: router_1
position: 6
@@ -476,132 +476,132 @@ agents:
src_wildcard: NONE
dst_wildcard: NONE
52: # old action num: 28
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 0
53: # old action num: 29
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 1
54: # old action num: 30
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 2
55: # old action num: 31
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 3
56: # old action num: 32
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 4
57: # old action num: 33
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 5
58: # old action num: 34
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 6
59: # old action num: 35
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 7
60: # old action num: 36
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 8
61: # old action num: 37
action: "router_acl_remove_rule"
action: "router-acl-remove-rule"
options:
target_router: router_1
position: 9
62: # old action num: 38
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: domain_controller
nic_num: 1
63: # old action num: 39
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: domain_controller
nic_num: 1
64: # old action num: 40
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: web_server
nic_num: 1
65: # old action num: 41
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: web_server
nic_num: 1
66: # old action num: 42
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: database_server
nic_num: 1
67: # old action num: 43
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: database_server
nic_num: 1
68: # old action num: 44
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: backup_server
nic_num: 1
69: # old action num: 45
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: backup_server
nic_num: 1
70: # old action num: 46
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: security_suite
nic_num: 1
71: # old action num: 47
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: security_suite
nic_num: 1
72: # old action num: 48
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: security_suite
nic_num: 2
73: # old action num: 49
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: security_suite
nic_num: 2
74: # old action num: 50
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: client_1
nic_num: 1
75: # old action num: 51
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: client_1
nic_num: 1
76: # old action num: 52
action: "host_nic_disable"
action: "host-nic-disable"
options:
node_name: client_2
nic_num: 1
77: # old action num: 53
action: "host_nic_enable"
action: "host-nic-enable"
options:
node_name: client_2
nic_num: 1
@@ -611,19 +611,19 @@ agents:
reward_function:
reward_components:
- type: DATABASE_FILE_INTEGRITY
- type: database-file-integrity
weight: 0.40
options:
node_hostname: database_server
folder_name: database
file_name: database.db
- type: SHARED_REWARD
- type: shared-reward
weight: 1.0
options:
agent_name: client_1_green_user
- type: SHARED_REWARD
- type: shared-reward
weight: 1.0
options:
agent_name: client_2_green_user
@@ -693,7 +693,7 @@ simulation:
subnet_mask: 255.255.255.0
default_gateway: 192.168.1.1
services:
- type: DNSServer
- type: dns-server
options:
domain_mapping:
arcd.com: 192.168.1.12 # web server
@@ -705,9 +705,9 @@ simulation:
default_gateway: 192.168.1.1
dns_server: 192.168.1.10
services:
- type: WebServer
- type: web-server
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 192.168.1.14
@@ -719,10 +719,10 @@ simulation:
default_gateway: 192.168.1.1
dns_server: 192.168.1.10
services:
- type: DatabaseService
- type: database-service
options:
backup_server_ip: 192.168.1.16
- type: FTPClient
- type: ftp-client
- hostname: backup_server
type: server
@@ -731,7 +731,7 @@ simulation:
default_gateway: 192.168.1.1
dns_server: 192.168.1.10
services:
- type: FTPServer
- type: ftp-server
- hostname: security_suite
type: server
@@ -751,20 +751,20 @@ simulation:
default_gateway: 192.168.10.1
dns_server: 192.168.1.10
applications:
- type: DataManipulationBot
- type: data-manipulation-bot
options:
port_scan_p_of_success: 0.8
data_manipulation_p_of_success: 0.8
payload: "DELETE"
server_ip: 192.168.1.14
- type: WebBrowser
- type: web-browser
options:
target_url: http://arcd.com/users/
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 192.168.1.14
services:
- type: DNSClient
- type: dns-client
- hostname: client_2
type: computer
@@ -773,20 +773,20 @@ simulation:
default_gateway: 192.168.10.1
dns_server: 192.168.1.10
applications:
- type: WebBrowser
- type: web-browser
options:
target_url: http://arcd.com/users/
- type: DataManipulationBot
- type: data-manipulation-bot
options:
port_scan_p_of_success: 0.8
data_manipulation_p_of_success: 0.8
payload: "DELETE"
server_ip: 192.168.1.14
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 192.168.1.14
services:
- type: DNSClient
- type: dns-client
links:
- endpoint_a_hostname: router_1

File diff suppressed because it is too large Load Diff

View File

@@ -5,46 +5,46 @@ game:
agents:
- ref: RL_Agent
type: ProxyAgent
type: proxy-agent
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_shutdown
action: node-shutdown
options:
node_name: client_1
2:
action: node_shutdown
action: node-shutdown
options:
node_name: server
3:
action: node_startup
action: node-startup
options:
node_name: client_1
4:
action: node_startup
action: node-startup
options:
node_name: server
5:
action: host_nic_disable
action: host-nic-disable
options:
node_name: client_1
nic_num: 1
6:
action: host_nic_disable
action: host-nic-disable
options:
node_name: server
nic_num: 1
7:
action: host_nic_enable
action: host-nic-enable
options:
node_name: client_1
nic_num: 1
8:
action: host_nic_enable
action: host-nic-enable
options:
node_name: server
nic_num: 1

View File

@@ -1,5 +1,5 @@
server_services: &server_services
- type: DatabaseService
- type: database-service
client_applications: &client_applications
- type: DatabaseClient
- type: database-client

View File

@@ -1,5 +1,5 @@
server_services: &server_services
- type: FTPServer
- type: ftp-server
client_applications: &client_applications
- type: RansomwareScript
- type: ransomware-script

View File

@@ -20,10 +20,10 @@ simulation:
default_gateway: 192.168.1.1
dns_server: 8.8.8.2
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
- type: WebBrowser
- type: web-browser
options:
target_url: http://sometech.ai/users/
@@ -34,10 +34,10 @@ simulation:
default_gateway: 192.168.1.1
dns_server: 8.8.8.2
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
- type: WebBrowser
- type: web-browser
options:
target_url: http://sometech.ai/users/
@@ -103,7 +103,7 @@ simulation:
default_gateway: 8.8.8.1
services:
- ref: dns_server
type: DNSServer
type: dns-server
options:
domain_mapping:
sometech.ai: 94.10.180.6
@@ -150,7 +150,7 @@ simulation:
dst_ip: 94.10.180.6
dst_port: POSTGRES_SERVER
dst_wildcard_mask: 0.0.0.0
8: # Permit SomeTech DMZ to use ARP
8: # Permit SomeTech DMZ to use arp
action: PERMIT
src_port: ARP
dst_port: ARP
@@ -170,7 +170,7 @@ simulation:
dst_ip: 10.10.1.11
dst_port: POSTGRES_SERVER
dst_wildcard_mask: 0.0.0.0
8: # Permit SomeTech DMZ to use ARP
8: # Permit SomeTech DMZ to use arp
action: PERMIT
src_port: ARP
dst_port: ARP
@@ -197,9 +197,9 @@ simulation:
dns_server: 8.8.8.2
services:
- ref: web_server
type: WebServer
type: web-server
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
@@ -269,12 +269,12 @@ simulation:
action: PERMIT
src_port: HTTP
dst_port: HTTP
18: # Allow the SomeTech internal network to use ARP
18: # Allow the SomeTech internal network to use arp
action: PERMIT
src_ip: 10.10.0.0
src_wildcard_mask: 0.0.255.255
src_port: ARP
19: # Allow the SomeTech internal network to use ICMP
19: # Allow the SomeTech internal network to use icmp
action: PERMIT
src_ip: 10.10.0.0
src_wildcard_mask: 0.0.255.255
@@ -318,10 +318,10 @@ simulation:
default_gateway: 10.10.1.1
dns_server: 8.8.8.2
services:
- type: DatabaseService
- type: database-service
options:
backup_server_ip: 10.10.1.12 # The some_tech_storage_srv server
- type: FTPClient
- type: ftp-client
- hostname: some_tech_storage_srv
type: server
@@ -330,7 +330,7 @@ simulation:
default_gateway: 10.10.1.1
dns_server: 8.8.8.2
services:
- type: FTPServer
- type: ftp-server
- hostname: some_tech_hr_1
type: computer
@@ -339,10 +339,10 @@ simulation:
default_gateway: 10.10.3.1
dns_server: 8.8.8.2
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
- type: WebBrowser
- type: web-browser
options:
target_url: http://sometech.ai/users/
@@ -353,10 +353,10 @@ simulation:
default_gateway: 10.10.2.1
dns_server: 8.8.8.2
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
- type: WebBrowser
- type: web-browser
options:
target_url: http://sometech.ai/users/
@@ -367,10 +367,10 @@ simulation:
default_gateway: 10.10.2.1
dns_server: 8.8.8.2
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 10.10.1.11
- type: WebBrowser
- type: web-browser
options:
target_url: http://sometech.ai/users/

View File

@@ -1,7 +1,7 @@
agents: &greens
- ref: green_A
team: GREEN
type: ProbabilisticAgent
type: probabilistic-agent
agent_settings:
action_probabilities:
0: 0.2
@@ -10,17 +10,17 @@ agents: &greens
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_application_execute
action: node-application-execute
options:
node_name: client
application_name: DatabaseClient
application_name: database-client
reward_function:
reward_components:
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
- type: green-admin-database-unreachable-penalty
weight: 1.0
options:
node_hostname: client

View File

@@ -1,7 +1,7 @@
agents: &greens
- ref: green_B
team: GREEN
type: ProbabilisticAgent
type: probabilistic-agent
agent_settings:
action_probabilities:
0: 0.95
@@ -10,17 +10,17 @@ agents: &greens
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_application_execute
action: node-application-execute
options:
node_name: client
application_name: DatabaseClient
application_name: database-client
reward_function:
reward_components:
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
- type: green-admin-database-unreachable-penalty
weight: 1.0
options:
node_hostname: client

View File

@@ -1,11 +1,11 @@
reds: &reds
- ref: red_A
team: RED
type: RedDatabaseCorruptingAgent
type: red-database-corrupting-agent
agent_settings:
possible_start_nodes: [client,]
target_application: DataManipulationBot
target_application: data-manipulation-bot
start_step: 10
frequency: 10
variance: 0

View File

@@ -1,11 +1,11 @@
reds: &reds
- ref: red_B
team: RED
type: RedDatabaseCorruptingAgent
type: red-database-corrupting-agent
agent_settings:
possible_start_nodes: [client_1]
target_application: DataManipulationBot
target_application: data-manipulation-bot
start_step: 3
frequency: 2
variance: 1

View File

@@ -26,12 +26,12 @@ agents:
- ref: defender
team: BLUE
type: ProxyAgent
type: proxy-agent
observation_space:
type: CUSTOM
type: custom
options:
components:
- type: NODES
- type: nodes
label: NODES
options:
routers: []
@@ -46,7 +46,7 @@ agents:
include_num_access: false
include_nmne: true
- type: LINKS
- type: links
label: LINKS
options:
link_references:
@@ -56,48 +56,48 @@ agents:
action_space:
action_map:
0:
action: do_nothing
action: do-nothing
options: {}
1:
action: node_shutdown
action: node-shutdown
options:
node_name: client_1
2:
action: node_shutdown
action: node-shutdown
options:
node_name: server
3:
action: node_startup
action: node-startup
options:
node_name: client_1
4:
action: node_startup
action: node-startup
options:
node_name: server
5:
action: host_nic_disable
action: host-nic-disable
options:
node_name: client_1
nic_num: 1
6:
action: host_nic_disable
action: host-nic-disable
options:
node_name: server
nic_num: 1
7:
action: host_nic_enable
action: host-nic-enable
options:
node_name: client_1
nic_num: 1
8:
action: host_nic_enable
action: host-nic-enable
options:
node_name: server
nic_num: 1
reward_function:
reward_components:
- type: DATABASE_FILE_INTEGRITY
- type: database-file-integrity
weight: 0.40
options:
node_hostname: database_server
@@ -121,10 +121,10 @@ simulation:
subnet_mask: 255.255.255.0
default_gateway: 192.168.1.1
applications:
- type: DatabaseClient
- type: database-client
options:
db_server_ip: 192.168.1.3
- type: DataManipulationBot
- type: data-manipulation-bot
options:
server_ip: 192.168.1.3
payload: "DELETE"
@@ -139,7 +139,7 @@ simulation:
subnet_mask: 255.255.255.0
default_gateway: 192.168.1.1
services:
- type: DatabaseService
- type: database-service
links:
- endpoint_a_hostname: client

View File

@@ -37,8 +37,8 @@ class ACLAddRuleAbstractAction(AbstractAction, ABC):
dst_wildcard: Union[IPV4Address, Literal["NONE"]]
class ACLRemoveRuleAbstractAction(AbstractAction, discriminator="acl_remove_rule_abstract_action"):
"""Base abstract class for ACL remove rule actions."""
class ACLRemoveRuleAbstractAction(AbstractAction, discriminator="acl-remove-rule-abstract-action"):
"""Base abstract class for acl remove rule actions."""
config: ConfigSchema = "ACLRemoveRuleAbstractAction.ConfigSchema"
@@ -48,8 +48,8 @@ class ACLRemoveRuleAbstractAction(AbstractAction, discriminator="acl_remove_rule
position: int
class RouterACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="router_acl_add_rule"):
"""Action which adds a rule to a router's ACL."""
class RouterACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="router-acl-add-rule"):
"""Action which adds a rule to a router's acl."""
config: "RouterACLAddRuleAction.ConfigSchema"
@@ -79,8 +79,8 @@ class RouterACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="router_acl
]
class RouterACLRemoveRuleAction(ACLRemoveRuleAbstractAction, discriminator="router_acl_remove_rule"):
"""Action which removes a rule from a router's ACL."""
class RouterACLRemoveRuleAction(ACLRemoveRuleAbstractAction, discriminator="router-acl-remove-rule"):
"""Action which removes a rule from a router's acl."""
config: "RouterACLRemoveRuleAction.ConfigSchema"
@@ -95,8 +95,8 @@ class RouterACLRemoveRuleAction(ACLRemoveRuleAbstractAction, discriminator="rout
return ["network", "node", config.target_router, "acl", "remove_rule", config.position]
class FirewallACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="firewall_acl_add_rule"):
"""Action which adds a rule to a firewall port's ACL."""
class FirewallACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="firewall-acl-add-rule"):
"""Action which adds a rule to a firewall port's acl."""
config: "FirewallACLAddRuleAction.ConfigSchema"
@@ -130,8 +130,8 @@ class FirewallACLAddRuleAction(ACLAddRuleAbstractAction, discriminator="firewall
]
class FirewallACLRemoveRuleAction(ACLRemoveRuleAbstractAction, discriminator="firewall_acl_remove_rule"):
"""Action which removes a rule from a firewall port's ACL."""
class FirewallACLRemoveRuleAction(ACLRemoveRuleAbstractAction, discriminator="firewall-acl-remove-rule"):
"""Action which removes a rule from a firewall port's acl."""
config: "FirewallACLRemoveRuleAction.ConfigSchema"

View File

@@ -45,7 +45,7 @@ class NodeApplicationAbstractAction(AbstractAction, ABC):
]
class NodeApplicationExecuteAction(NodeApplicationAbstractAction, discriminator="node_application_execute"):
class NodeApplicationExecuteAction(NodeApplicationAbstractAction, discriminator="node-application-execute"):
"""Action which executes an application."""
config: "NodeApplicationExecuteAction.ConfigSchema"
@@ -56,7 +56,7 @@ class NodeApplicationExecuteAction(NodeApplicationAbstractAction, discriminator=
verb: str = "execute"
class NodeApplicationScanAction(NodeApplicationAbstractAction, discriminator="node_application_scan"):
class NodeApplicationScanAction(NodeApplicationAbstractAction, discriminator="node-application-scan"):
"""Action which scans an application."""
config: "NodeApplicationScanAction.ConfigSchema"
@@ -67,7 +67,7 @@ class NodeApplicationScanAction(NodeApplicationAbstractAction, discriminator="no
verb: str = "scan"
class NodeApplicationCloseAction(NodeApplicationAbstractAction, discriminator="node_application_close"):
class NodeApplicationCloseAction(NodeApplicationAbstractAction, discriminator="node-application-close"):
"""Action which closes an application."""
config: "NodeApplicationCloseAction.ConfigSchema"
@@ -78,7 +78,7 @@ class NodeApplicationCloseAction(NodeApplicationAbstractAction, discriminator="n
verb: str = "close"
class NodeApplicationFixAction(NodeApplicationAbstractAction, discriminator="node_application_fix"):
class NodeApplicationFixAction(NodeApplicationAbstractAction, discriminator="node-application-fix"):
"""Action which fixes an application."""
config: "NodeApplicationFixAction.ConfigSchema"
@@ -89,7 +89,7 @@ class NodeApplicationFixAction(NodeApplicationAbstractAction, discriminator="nod
verb: str = "fix"
class NodeApplicationInstallAction(NodeApplicationAbstractAction, discriminator="node_application_install"):
class NodeApplicationInstallAction(NodeApplicationAbstractAction, discriminator="node-application-install"):
"""Action which installs an application."""
config: "NodeApplicationInstallAction.ConfigSchema"
@@ -113,7 +113,7 @@ class NodeApplicationInstallAction(NodeApplicationAbstractAction, discriminator=
]
class NodeApplicationRemoveAction(NodeApplicationAbstractAction, discriminator="node_application_remove"):
class NodeApplicationRemoveAction(NodeApplicationAbstractAction, discriminator="node-application-remove"):
"""Action which removes/uninstalls an application."""
config: "NodeApplicationRemoveAction.ConfigSchema"

View File

@@ -38,7 +38,7 @@ class NodeFileAbstractAction(AbstractAction, ABC):
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None or config.file_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -52,7 +52,7 @@ class NodeFileAbstractAction(AbstractAction, ABC):
]
class NodeFileCreateAction(NodeFileAbstractAction, discriminator="node_file_create"):
class NodeFileCreateAction(NodeFileAbstractAction, discriminator="node-file-create"):
"""Action which creates a new file in a given folder."""
config: "NodeFileCreateAction.ConfigSchema"
@@ -67,7 +67,7 @@ class NodeFileCreateAction(NodeFileAbstractAction, discriminator="node_file_crea
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None or config.file_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -81,7 +81,7 @@ class NodeFileCreateAction(NodeFileAbstractAction, discriminator="node_file_crea
]
class NodeFileScanAction(NodeFileAbstractAction, discriminator="node_file_scan"):
class NodeFileScanAction(NodeFileAbstractAction, discriminator="node-file-scan"):
"""Action which scans a file."""
config: "NodeFileScanAction.ConfigSchema"
@@ -92,7 +92,7 @@ class NodeFileScanAction(NodeFileAbstractAction, discriminator="node_file_scan")
verb: ClassVar[str] = "scan"
class NodeFileDeleteAction(NodeFileAbstractAction, discriminator="node_file_delete"):
class NodeFileDeleteAction(NodeFileAbstractAction, discriminator="node-file-delete"):
"""Action which deletes a file."""
config: "NodeFileDeleteAction.ConfigSchema"
@@ -106,7 +106,7 @@ class NodeFileDeleteAction(NodeFileAbstractAction, discriminator="node_file_dele
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None or config.file_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -119,7 +119,7 @@ class NodeFileDeleteAction(NodeFileAbstractAction, discriminator="node_file_dele
]
class NodeFileRestoreAction(NodeFileAbstractAction, discriminator="node_file_restore"):
class NodeFileRestoreAction(NodeFileAbstractAction, discriminator="node-file-restore"):
"""Action which restores a file."""
config: "NodeFileRestoreAction.ConfigSchema"
@@ -130,7 +130,7 @@ class NodeFileRestoreAction(NodeFileAbstractAction, discriminator="node_file_res
verb: ClassVar[str] = "restore"
class NodeFileCorruptAction(NodeFileAbstractAction, discriminator="node_file_corrupt"):
class NodeFileCorruptAction(NodeFileAbstractAction, discriminator="node-file-corrupt"):
"""Action which corrupts a file."""
config: "NodeFileCorruptAction.ConfigSchema"
@@ -141,7 +141,7 @@ class NodeFileCorruptAction(NodeFileAbstractAction, discriminator="node_file_cor
verb: ClassVar[str] = "corrupt"
class NodeFileAccessAction(NodeFileAbstractAction, discriminator="node_file_access"):
class NodeFileAccessAction(NodeFileAbstractAction, discriminator="node-file-access"):
"""Action which increases a file's access count."""
config: "NodeFileAccessAction.ConfigSchema"
@@ -155,7 +155,7 @@ class NodeFileAccessAction(NodeFileAbstractAction, discriminator="node_file_acce
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None or config.file_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -167,7 +167,7 @@ class NodeFileAccessAction(NodeFileAbstractAction, discriminator="node_file_acce
]
class NodeFileCheckhashAction(NodeFileAbstractAction, discriminator="node_file_checkhash"):
class NodeFileCheckhashAction(NodeFileAbstractAction, discriminator="node-file-checkhash"):
"""Action which checks the hash of a file."""
config: "NodeFileCheckhashAction.ConfigSchema"
@@ -178,7 +178,7 @@ class NodeFileCheckhashAction(NodeFileAbstractAction, discriminator="node_file_c
verb: ClassVar[str] = "checkhash"
class NodeFileRepairAction(NodeFileAbstractAction, discriminator="node_file_repair"):
class NodeFileRepairAction(NodeFileAbstractAction, discriminator="node-file-repair"):
"""Action which repairs a file."""
config: "NodeFileRepairAction.ConfigSchema"

View File

@@ -35,7 +35,7 @@ class NodeFolderAbstractAction(AbstractAction, ABC):
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -47,7 +47,7 @@ class NodeFolderAbstractAction(AbstractAction, ABC):
]
class NodeFolderScanAction(NodeFolderAbstractAction, discriminator="node_folder_scan"):
class NodeFolderScanAction(NodeFolderAbstractAction, discriminator="node-folder-scan"):
"""Action which scans a folder."""
config: "NodeFolderScanAction.ConfigSchema"
@@ -58,7 +58,7 @@ class NodeFolderScanAction(NodeFolderAbstractAction, discriminator="node_folder_
verb: ClassVar[str] = "scan"
class NodeFolderCheckhashAction(NodeFolderAbstractAction, discriminator="node_folder_checkhash"):
class NodeFolderCheckhashAction(NodeFolderAbstractAction, discriminator="node-folder-checkhash"):
"""Action which checks the hash of a folder."""
config: "NodeFolderCheckhashAction.ConfigSchema"
@@ -69,7 +69,7 @@ class NodeFolderCheckhashAction(NodeFolderAbstractAction, discriminator="node_fo
verb: ClassVar[str] = "checkhash"
class NodeFolderRepairAction(NodeFolderAbstractAction, discriminator="node_folder_repair"):
class NodeFolderRepairAction(NodeFolderAbstractAction, discriminator="node-folder-repair"):
"""Action which repairs a folder."""
config: "NodeFolderRepairAction.ConfigSchema"
@@ -80,7 +80,7 @@ class NodeFolderRepairAction(NodeFolderAbstractAction, discriminator="node_folde
verb: ClassVar[str] = "repair"
class NodeFolderRestoreAction(NodeFolderAbstractAction, discriminator="node_folder_restore"):
class NodeFolderRestoreAction(NodeFolderAbstractAction, discriminator="node-folder-restore"):
"""Action which restores a folder."""
config: "NodeFolderRestoreAction.ConfigSchema"
@@ -91,7 +91,7 @@ class NodeFolderRestoreAction(NodeFolderAbstractAction, discriminator="node_fold
verb: ClassVar[str] = "restore"
class NodeFolderCreateAction(NodeFolderAbstractAction, discriminator="node_folder_create"):
class NodeFolderCreateAction(NodeFolderAbstractAction, discriminator="node-folder-create"):
"""Action which creates a new folder."""
config: "NodeFolderCreateAction.ConfigSchema"
@@ -105,7 +105,7 @@ class NodeFolderCreateAction(NodeFolderAbstractAction, discriminator="node_folde
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.folder_name is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",

View File

@@ -29,7 +29,7 @@ class HostNICAbstractAction(AbstractAction, ABC):
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.nic_num is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -40,7 +40,7 @@ class HostNICAbstractAction(AbstractAction, ABC):
]
class HostNICEnableAction(HostNICAbstractAction, discriminator="host_nic_enable"):
class HostNICEnableAction(HostNICAbstractAction, discriminator="host-nic-enable"):
"""Action which enables a NIC."""
config: "HostNICEnableAction.ConfigSchema"
@@ -51,7 +51,7 @@ class HostNICEnableAction(HostNICAbstractAction, discriminator="host_nic_enable"
verb: ClassVar[str] = "enable"
class HostNICDisableAction(HostNICAbstractAction, discriminator="host_nic_disable"):
class HostNICDisableAction(HostNICAbstractAction, discriminator="host-nic-disable"):
"""Action which disables a NIC."""
config: "HostNICDisableAction.ConfigSchema"

View File

@@ -5,9 +5,9 @@ agents:
- name: agent_1
action_space:
actions:
- do_nothing
- node_service_start
- node_service_stop
- do-nothing
- node-service-start
- node-service-stop
action_map:
"""
@@ -24,18 +24,18 @@ from primaite.interface.request import RequestFormat
__all__ = ("DoNothingAction", "ActionManager")
class DoNothingAction(AbstractAction, discriminator="do_nothing"):
class DoNothingAction(AbstractAction, discriminator="do-nothing"):
"""Do Nothing Action."""
class ConfigSchema(AbstractAction.ConfigSchema):
"""Configuration Schema for do_nothingAction."""
type: str = "do_nothing"
type: str = "do-nothing"
@classmethod
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
return ["do_nothing"]
return ["do-nothing"]
class _ActionMapItem(BaseModel):

View File

@@ -8,7 +8,7 @@ from primaite.interface.request import RequestFormat
__all__ = ("NetworkPortEnableAction", "NetworkPortDisableAction")
class NetworkPortAbstractAction(AbstractAction, discriminator="network_port_abstract"):
class NetworkPortAbstractAction(AbstractAction, discriminator="network-port-abstract"):
"""Base class for Network port actions."""
config: "NetworkPortAbstractAction.ConfigSchema"
@@ -24,7 +24,7 @@ class NetworkPortAbstractAction(AbstractAction, discriminator="network_port_abst
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.target_nodename is None or config.port_num is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
@@ -35,7 +35,7 @@ class NetworkPortAbstractAction(AbstractAction, discriminator="network_port_abst
]
class NetworkPortEnableAction(NetworkPortAbstractAction, discriminator="network_port_enable"):
class NetworkPortEnableAction(NetworkPortAbstractAction, discriminator="network-port-enable"):
"""Action which enables are port on a router or a firewall."""
config: "NetworkPortEnableAction.ConfigSchema"
@@ -46,7 +46,7 @@ class NetworkPortEnableAction(NetworkPortAbstractAction, discriminator="network_
verb: ClassVar[str] = "enable"
class NetworkPortDisableAction(NetworkPortAbstractAction, discriminator="network_port_disable"):
class NetworkPortDisableAction(NetworkPortAbstractAction, discriminator="network-port-disable"):
"""Action which disables are port on a router or a firewall."""
config: "NetworkPortDisableAction.ConfigSchema"

View File

@@ -18,7 +18,7 @@ __all__ = (
)
class NodeAbstractAction(AbstractAction, discriminator="node_abstract"):
class NodeAbstractAction(AbstractAction, discriminator="node-abstract"):
"""
Abstract base class for node actions.
@@ -39,7 +39,7 @@ class NodeAbstractAction(AbstractAction, discriminator="node_abstract"):
return ["network", "node", config.node_name, config.verb]
class NodeOSScanAction(NodeAbstractAction, discriminator="node_os_scan"):
class NodeOSScanAction(NodeAbstractAction, discriminator="node-os-scan"):
"""Action which scans a node's OS."""
config: "NodeOSScanAction.ConfigSchema"
@@ -50,7 +50,7 @@ class NodeOSScanAction(NodeAbstractAction, discriminator="node_os_scan"):
verb: ClassVar[str] = "scan"
class NodeShutdownAction(NodeAbstractAction, discriminator="node_shutdown"):
class NodeShutdownAction(NodeAbstractAction, discriminator="node-shutdown"):
"""Action which shuts down a node."""
config: "NodeShutdownAction.ConfigSchema"
@@ -61,7 +61,7 @@ class NodeShutdownAction(NodeAbstractAction, discriminator="node_shutdown"):
verb: ClassVar[str] = "shutdown"
class NodeStartupAction(NodeAbstractAction, discriminator="node_startup"):
class NodeStartupAction(NodeAbstractAction, discriminator="node-startup"):
"""Action which starts up a node."""
config: "NodeStartupAction.ConfigSchema"
@@ -72,7 +72,7 @@ class NodeStartupAction(NodeAbstractAction, discriminator="node_startup"):
verb: ClassVar[str] = "startup"
class NodeResetAction(NodeAbstractAction, discriminator="node_reset"):
class NodeResetAction(NodeAbstractAction, discriminator="node-reset"):
"""Action which resets a node."""
config: "NodeResetAction.ConfigSchema"
@@ -83,7 +83,7 @@ class NodeResetAction(NodeAbstractAction, discriminator="node_reset"):
verb: ClassVar[str] = "reset"
class NodeNMAPAbstractAction(AbstractAction, discriminator="node_nmap_abstract_action"):
class NodeNMAPAbstractAction(AbstractAction, discriminator="node-nmap-abstract-action"):
"""Base class for NodeNMAP actions."""
config: "NodeNMAPAbstractAction.ConfigSchema"
@@ -103,8 +103,8 @@ class NodeNMAPAbstractAction(AbstractAction, discriminator="node_nmap_abstract_a
pass
class NodeNMAPPingScanAction(NodeNMAPAbstractAction, discriminator="node_nmap_ping_scan"):
"""Action which performs an NMAP ping scan."""
class NodeNMAPPingScanAction(NodeNMAPAbstractAction, discriminator="node-nmap-ping-scan"):
"""Action which performs an nmap ping scan."""
config: "NodeNMAPPingScanAction.ConfigSchema"
@@ -116,14 +116,14 @@ class NodeNMAPPingScanAction(NodeNMAPAbstractAction, discriminator="node_nmap_pi
"node",
config.source_node,
"application",
"NMAP",
"nmap",
"ping_scan",
{"target_ip_address": config.target_ip_address, "show": config.show},
]
class NodeNMAPPortScanAction(NodeNMAPAbstractAction, discriminator="node_nmap_port_scan"):
"""Action which performs an NMAP port scan."""
class NodeNMAPPortScanAction(NodeNMAPAbstractAction, discriminator="node-nmap-port-scan"):
"""Action which performs an nmap port scan."""
config: "NodeNMAPPortScanAction.ConfigSchema"
@@ -143,7 +143,7 @@ class NodeNMAPPortScanAction(NodeNMAPAbstractAction, discriminator="node_nmap_po
"node",
config.source_node,
"application",
"NMAP",
"nmap",
"port_scan",
{
"target_ip_address": config.target_ip_address,
@@ -154,8 +154,8 @@ class NodeNMAPPortScanAction(NodeNMAPAbstractAction, discriminator="node_nmap_po
]
class NodeNetworkServiceReconAction(NodeNMAPAbstractAction, discriminator="node_network_service_recon"):
"""Action which performs an NMAP network service recon (ping scan followed by port scan)."""
class NodeNetworkServiceReconAction(NodeNMAPAbstractAction, discriminator="node-network-service-recon"):
"""Action which performs an nmap network service recon (ping scan followed by port scan)."""
config: "NodeNetworkServiceReconAction.ConfigSchema"
@@ -174,7 +174,7 @@ class NodeNetworkServiceReconAction(NodeNMAPAbstractAction, discriminator="node_
"node",
config.source_node,
"application",
"NMAP",
"nmap",
"network_service_recon",
{
"target_ip_address": config.target_ip_address,

View File

@@ -17,7 +17,7 @@ __all__ = (
)
class NodeServiceAbstractAction(AbstractAction, discriminator="node_service_abstract"):
class NodeServiceAbstractAction(AbstractAction, discriminator="node-service-abstract"):
"""Abstract Action for Node Service related actions.
Any actions which use node_name and service_name can inherit from this class.
@@ -36,7 +36,7 @@ class NodeServiceAbstractAction(AbstractAction, discriminator="node_service_abst
return ["network", "node", config.node_name, "service", config.service_name, config.verb]
class NodeServiceScanAction(NodeServiceAbstractAction, discriminator="node_service_scan"):
class NodeServiceScanAction(NodeServiceAbstractAction, discriminator="node-service-scan"):
"""Action which scans a service."""
config: "NodeServiceScanAction.ConfigSchema"
@@ -47,7 +47,7 @@ class NodeServiceScanAction(NodeServiceAbstractAction, discriminator="node_servi
verb: ClassVar[str] = "scan"
class NodeServiceStopAction(NodeServiceAbstractAction, discriminator="node_service_stop"):
class NodeServiceStopAction(NodeServiceAbstractAction, discriminator="node-service-stop"):
"""Action which stops a service."""
config: "NodeServiceStopAction.ConfigSchema"
@@ -58,7 +58,7 @@ class NodeServiceStopAction(NodeServiceAbstractAction, discriminator="node_servi
verb: ClassVar[str] = "stop"
class NodeServiceStartAction(NodeServiceAbstractAction, discriminator="node_service_start"):
class NodeServiceStartAction(NodeServiceAbstractAction, discriminator="node-service-start"):
"""Action which starts a service."""
config: "NodeServiceStartAction.ConfigSchema"
@@ -69,7 +69,7 @@ class NodeServiceStartAction(NodeServiceAbstractAction, discriminator="node_serv
verb: ClassVar[str] = "start"
class NodeServicePauseAction(NodeServiceAbstractAction, discriminator="node_service_pause"):
class NodeServicePauseAction(NodeServiceAbstractAction, discriminator="node-service-pause"):
"""Action which pauses a service."""
config: "NodeServicePauseAction.ConfigSchema"
@@ -80,7 +80,7 @@ class NodeServicePauseAction(NodeServiceAbstractAction, discriminator="node_serv
verb: ClassVar[str] = "pause"
class NodeServiceResumeAction(NodeServiceAbstractAction, discriminator="node_service_resume"):
class NodeServiceResumeAction(NodeServiceAbstractAction, discriminator="node-service-resume"):
"""Action which resumes a service."""
config: "NodeServiceResumeAction.ConfigSchema"
@@ -91,7 +91,7 @@ class NodeServiceResumeAction(NodeServiceAbstractAction, discriminator="node_ser
verb: ClassVar[str] = "resume"
class NodeServiceRestartAction(NodeServiceAbstractAction, discriminator="node_service_restart"):
class NodeServiceRestartAction(NodeServiceAbstractAction, discriminator="node-service-restart"):
"""Action which restarts a service."""
config: "NodeServiceRestartAction.ConfigSchema"
@@ -102,7 +102,7 @@ class NodeServiceRestartAction(NodeServiceAbstractAction, discriminator="node_se
verb: ClassVar[str] = "restart"
class NodeServiceDisableAction(NodeServiceAbstractAction, discriminator="node_service_disable"):
class NodeServiceDisableAction(NodeServiceAbstractAction, discriminator="node-service-disable"):
"""Action which disables a service."""
config: "NodeServiceDisableAction.ConfigSchema"
@@ -113,7 +113,7 @@ class NodeServiceDisableAction(NodeServiceAbstractAction, discriminator="node_se
verb: ClassVar[str] = "disable"
class NodeServiceEnableAction(NodeServiceAbstractAction, discriminator="node_service_enable"):
class NodeServiceEnableAction(NodeServiceAbstractAction, discriminator="node-service-enable"):
"""Action which enables a service."""
config: "NodeServiceEnableAction.ConfigSchema"
@@ -124,7 +124,7 @@ class NodeServiceEnableAction(NodeServiceAbstractAction, discriminator="node_ser
verb: ClassVar[str] = "enable"
class NodeServiceFixAction(NodeServiceAbstractAction, discriminator="node_service_fix"):
class NodeServiceFixAction(NodeServiceAbstractAction, discriminator="node-service-fix"):
"""Action which fixes a service."""
config: "NodeServiceFixAction.ConfigSchema"

View File

@@ -11,7 +11,7 @@ __all__ = (
)
class NodeSessionAbstractAction(AbstractAction, discriminator="node_session_abstract"):
class NodeSessionAbstractAction(AbstractAction, discriminator="node-session-abstract"):
"""Base class for NodeSession actions."""
config: "NodeSessionAbstractAction.ConfigSchema"
@@ -33,7 +33,7 @@ class NodeSessionAbstractAction(AbstractAction, discriminator="node_session_abst
pass
class NodeSessionsRemoteLoginAction(NodeSessionAbstractAction, discriminator="node_session_remote_login"):
class NodeSessionsRemoteLoginAction(NodeSessionAbstractAction, discriminator="node-session-remote-login"):
"""Action which performs a remote session login."""
config: "NodeSessionsRemoteLoginAction.ConfigSchema"
@@ -48,21 +48,21 @@ class NodeSessionsRemoteLoginAction(NodeSessionAbstractAction, discriminator="no
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.remote_ip is None:
return ["do_nothing"]
return ["do-nothing"]
return [
"network",
"node",
config.node_name,
"service",
"Terminal",
"node_session_remote_login",
"terminal",
"node-session-remote-login",
config.username,
config.password,
config.remote_ip,
]
class NodeSessionsRemoteLogoutAction(NodeSessionAbstractAction, discriminator="node_session_remote_logoff"):
class NodeSessionsRemoteLogoutAction(NodeSessionAbstractAction, discriminator="node-session-remote-logoff"):
"""Action which performs a remote session logout."""
config: "NodeSessionsRemoteLogoutAction.ConfigSchema"
@@ -76,11 +76,11 @@ class NodeSessionsRemoteLogoutAction(NodeSessionAbstractAction, discriminator="n
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
if config.node_name is None or config.remote_ip is None:
return ["do_nothing"]
return ["network", "node", config.node_name, "service", "Terminal", config.verb, config.remote_ip]
return ["do-nothing"]
return ["network", "node", config.node_name, "service", "terminal", config.verb, config.remote_ip]
class NodeAccountChangePasswordAction(NodeSessionAbstractAction, discriminator="node_account_change_password"):
class NodeAccountChangePasswordAction(NodeSessionAbstractAction, discriminator="node-account-change-password"):
"""Action which changes the password for a user."""
config: "NodeAccountChangePasswordAction.ConfigSchema"
@@ -100,7 +100,7 @@ class NodeAccountChangePasswordAction(NodeSessionAbstractAction, discriminator="
"node",
config.node_name,
"service",
"UserManager",
"user-manager",
"change_password",
config.username,
config.current_password,

View File

@@ -22,7 +22,7 @@ __all__ = (
)
class ConfigureRansomwareScriptAction(AbstractAction, discriminator="configure_ransomware_script"):
class ConfigureRansomwareScriptAction(AbstractAction, discriminator="configure-ransomware-script"):
"""Action which sets config parameters for a ransomware script on a node."""
config: "ConfigureRansomwareScriptAction.ConfigSchema"
@@ -39,17 +39,17 @@ class ConfigureRansomwareScriptAction(AbstractAction, discriminator="configure_r
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request that can be ingested by the simulation."""
if config.node_name is None:
return ["do_nothing"]
return ["do-nothing"]
data = dict(
server_ip_address=config.server_ip_address,
server_password=config.server_password,
payload=config.payload,
)
return ["network", "node", config.node_name, "application", "RansomwareScript", "configure", data]
return ["network", "node", config.node_name, "application", "ransomware-script", "configure", data]
class RansomwareConfigureC2ServerAction(
ConfigureRansomwareScriptAction, discriminator="c2_server_ransomware_configure"
ConfigureRansomwareScriptAction, discriminator="c2-server-ransomware-configure"
):
"""Action which causes a C2 server to send a command to set options on a ransomware script remotely."""
@@ -58,10 +58,10 @@ class RansomwareConfigureC2ServerAction(
data = dict(
server_ip_address=config.server_ip_address, server_password=config.server_password, payload=config.payload
)
return ["network", "node", config.node_name, "application", "C2Server", "ransomware_configure", data]
return ["network", "node", config.node_name, "application", "c2-server", "ransomware_configure", data]
class ConfigureDoSBotAction(AbstractAction, discriminator="configure_dos_bot"):
class ConfigureDoSBotAction(AbstractAction, discriminator="configure-dos-bot"):
"""Action which sets config parameters for a DoS bot on a node."""
class ConfigSchema(AbstractAction.ConfigSchema):
@@ -90,10 +90,10 @@ class ConfigureDoSBotAction(AbstractAction, discriminator="configure_dos_bot"):
max_sessions=config.max_sessions,
)
data = {k: v for k, v in data.items() if v is not None}
return ["network", "node", config.node_name, "application", "DoSBot", "configure", data]
return ["network", "node", config.node_name, "application", "dos-bot", "configure", data]
class ConfigureC2BeaconAction(AbstractAction, discriminator="configure_c2_beacon"):
class ConfigureC2BeaconAction(AbstractAction, discriminator="configure-c2-beacon"):
"""Action which configures a C2 Beacon based on the parameters given."""
class ConfigSchema(AbstractAction.ConfigSchema):
@@ -114,10 +114,10 @@ class ConfigureC2BeaconAction(AbstractAction, discriminator="configure_c2_beacon
masquerade_protocol=config.masquerade_protocol,
masquerade_port=config.masquerade_port,
)
return ["network", "node", config.node_name, "application", "C2Beacon", "configure", data]
return ["network", "node", config.node_name, "application", "c2-beacon", "configure", data]
class NodeSendRemoteCommandAction(AbstractAction, discriminator="node_send_remote_command"):
class NodeSendRemoteCommandAction(AbstractAction, discriminator="node-send-remote-command"):
"""Action which sends a terminal command to a remote node via SSH."""
config: "NodeSendRemoteCommandAction.ConfigSchema"
@@ -137,14 +137,14 @@ class NodeSendRemoteCommandAction(AbstractAction, discriminator="node_send_remot
"node",
config.node_name,
"service",
"Terminal",
"terminal",
"send_remote_command",
config.remote_ip,
{"command": config.command},
]
class TerminalC2ServerAction(AbstractAction, discriminator="c2_server_terminal_command"):
class TerminalC2ServerAction(AbstractAction, discriminator="c2-server-terminal-command"):
"""Action which causes the C2 Server to send a command to the C2 Beacon to execute the terminal command passed."""
config: "TerminalC2ServerAction.ConfigSchema"
@@ -162,7 +162,7 @@ class TerminalC2ServerAction(AbstractAction, discriminator="c2_server_terminal_c
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request that can be ingested by the simulation."""
if config.node_name is None:
return ["do_nothing"]
return ["do-nothing"]
command_model = {
"commands": config.commands,
@@ -170,10 +170,10 @@ class TerminalC2ServerAction(AbstractAction, discriminator="c2_server_terminal_c
"username": config.username,
"password": config.password,
}
return ["network", "node", config.node_name, "application", "C2Server", "terminal_command", command_model]
return ["network", "node", config.node_name, "application", "c2-server", "terminal_command", command_model]
class RansomwareLaunchC2ServerAction(AbstractAction, discriminator="c2_server_ransomware_launch"):
class RansomwareLaunchC2ServerAction(AbstractAction, discriminator="c2-server-ransomware-launch"):
"""Action which causes the C2 Server to send a command to the C2 Beacon to launch the RansomwareScript."""
config: "RansomwareLaunchC2ServerAction.ConfigSchema"
@@ -187,12 +187,12 @@ class RansomwareLaunchC2ServerAction(AbstractAction, discriminator="c2_server_ra
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request that can be ingested by the simulation."""
if config.node_name is None:
return ["do_nothing"]
return ["do-nothing"]
# This action currently doesn't require any further configuration options.
return ["network", "node", config.node_name, "application", "C2Server", "ransomware_launch"]
return ["network", "node", config.node_name, "application", "c2-server", "ransomware_launch"]
class ExfiltrationC2ServerAction(AbstractAction, discriminator="c2_server_data_exfiltrate"):
class ExfiltrationC2ServerAction(AbstractAction, discriminator="c2-server-data-exfiltrate"):
"""Action which exfiltrates a target file from a certain node onto the C2 beacon and then the C2 Server."""
config: "ExfiltrationC2ServerAction.ConfigSchema"
@@ -212,7 +212,7 @@ class ExfiltrationC2ServerAction(AbstractAction, discriminator="c2_server_data_e
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request that can be ingested by the simulation."""
if config.node_name is None:
return ["do_nothing"]
return ["do-nothing"]
command_model = {
"target_file_name": config.target_file_name,
@@ -222,10 +222,10 @@ class ExfiltrationC2ServerAction(AbstractAction, discriminator="c2_server_data_e
"username": config.username,
"password": config.password,
}
return ["network", "node", config.node_name, "application", "C2Server", "exfiltrate", command_model]
return ["network", "node", config.node_name, "application", "c2-server", "exfiltrate", command_model]
class ConfigureDatabaseClientAction(AbstractAction, discriminator="configure_database_client"):
class ConfigureDatabaseClientAction(AbstractAction, discriminator="configure-database-client"):
"""Action which sets config parameters for a database client on a node."""
config: "ConfigureDatabaseClientAction.ConfigSchema"
@@ -241,6 +241,6 @@ class ConfigureDatabaseClientAction(AbstractAction, discriminator="configure_dat
def form_request(cls, config: ConfigSchema) -> RequestFormat:
"""Return the action formatted as a request that can be ingested by the simulation."""
if config.node_name is None:
return ["do_nothing"]
return ["do-nothing"]
data = {"server_ip_address": config.server_ip_address, "server_password": config.server_password}
return ["network", "node", config.node_name, "application", "DatabaseClient", "configure", data]
return ["network", "node", config.node_name, "application", "database-client", "configure", data]

View File

@@ -130,7 +130,7 @@ class AbstractAgent(BaseModel, ABC):
"""
# in RL agent, this method will send CAOS observation to RL agent, then receive a int 0-39,
# then use a bespoke conversion to take 1-40 int back into CAOS action
return ("do_nothing", {})
return ("do-nothing", {})
def format_request(self, action: Tuple[str, Dict], options: Dict[str, int]) -> RequestFormat:
# this will take something like APPLICATION.EXECUTE and add things like target_ip_address in simulator.
@@ -161,7 +161,7 @@ class AbstractAgent(BaseModel, ABC):
return agent_class(config=config)
class AbstractScriptedAgent(AbstractAgent, discriminator="AbstractScriptedAgent"):
class AbstractScriptedAgent(AbstractAgent, discriminator="abstract-scripted-agent"):
"""Base class for actors which generate their own behaviour."""
config: "AbstractScriptedAgent.ConfigSchema" = Field(default_factory=lambda: AbstractScriptedAgent.ConfigSchema())
@@ -177,7 +177,7 @@ class AbstractScriptedAgent(AbstractAgent, discriminator="AbstractScriptedAgent"
return super().get_action(obs=obs, timestep=timestep)
class ProxyAgent(AbstractAgent, discriminator="ProxyAgent"):
class ProxyAgent(AbstractAgent, discriminator="proxy-agent"):
"""Agent that sends observations to an RL model and receives actions from that model."""
config: "ProxyAgent.ConfigSchema" = Field(default_factory=lambda: ProxyAgent.ConfigSchema())

View File

@@ -16,7 +16,7 @@ from primaite.utils.validation.port import Port
_LOGGER = getLogger(__name__)
class ACLObservation(AbstractObservation, discriminator="ACL"):
class ACLObservation(AbstractObservation, discriminator="acl"):
"""ACL observation, provides information about access control lists within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -13,7 +13,7 @@ from primaite.game.agent.utils import access_from_nested_dict, NOT_PRESENT_IN_ST
_LOGGER = getLogger(__name__)
class FileObservation(AbstractObservation, discriminator="FILE"):
class FileObservation(AbstractObservation, discriminator="file"):
"""File observation, provides status information about a file within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -125,7 +125,7 @@ class FileObservation(AbstractObservation, discriminator="FILE"):
)
class FolderObservation(AbstractObservation, discriminator="FOLDER"):
class FolderObservation(AbstractObservation, discriminator="folder"):
"""Folder observation, provides status information about a folder within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -18,7 +18,7 @@ from primaite.utils.validation.port import Port
_LOGGER = getLogger(__name__)
class FirewallObservation(AbstractObservation, discriminator="FIREWALL"):
class FirewallObservation(AbstractObservation, discriminator="firewall"):
"""Firewall observation, provides status information about a firewall within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -181,7 +181,7 @@ class FirewallObservation(AbstractObservation, discriminator="FIREWALL"):
},
}
if self.include_users:
sess = firewall_state["services"]["UserSessionManager"]
sess = firewall_state["services"]["user-session-manager"]
obs["users"] = {
"local_login": 1 if sess["current_local_user"] else 0,
"remote_sessions": min(self.max_users, len(sess["active_remote_sessions"])),

View File

@@ -18,7 +18,7 @@ from primaite.utils.validation.port import Port
_LOGGER = getLogger(__name__)
class HostObservation(AbstractObservation, discriminator="HOST"):
class HostObservation(AbstractObservation, discriminator="host"):
"""Host observation, provides status information about a host within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -209,7 +209,7 @@ class HostObservation(AbstractObservation, discriminator="HOST"):
obs["num_file_creations"] = node_state["file_system"]["num_file_creations"]
obs["num_file_deletions"] = node_state["file_system"]["num_file_deletions"]
if self.include_users:
sess = node_state["services"]["UserSessionManager"]
sess = node_state["services"]["user-session-manager"]
obs["users"] = {
"local_login": 1 if sess["current_local_user"] else 0,
"remote_sessions": min(self.max_users, len(sess["active_remote_sessions"])),

View File

@@ -13,7 +13,7 @@ from primaite.game.agent.utils import access_from_nested_dict, NOT_PRESENT_IN_ST
_LOGGER = getLogger(__name__)
class LinkObservation(AbstractObservation, discriminator="LINK"):
class LinkObservation(AbstractObservation, discriminator="link"):
"""Link observation, providing information about a specific link within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -90,7 +90,7 @@ class LinkObservation(AbstractObservation, discriminator="LINK"):
return cls(where=where)
class LinksObservation(AbstractObservation, discriminator="LINKS"):
class LinksObservation(AbstractObservation, discriminator="links"):
"""Collection of link observations representing multiple links within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -12,7 +12,7 @@ from primaite.utils.validation.ip_protocol import IPProtocol
from primaite.utils.validation.port import Port
class NICObservation(AbstractObservation, discriminator="NETWORK_INTERFACE"):
class NICObservation(AbstractObservation, discriminator="network-interface"):
"""Status information about a network interface within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -227,7 +227,7 @@ class NICObservation(AbstractObservation, discriminator="NETWORK_INTERFACE"):
)
class PortObservation(AbstractObservation, discriminator="PORT"):
class PortObservation(AbstractObservation, discriminator="port"):
"""Port observation, provides status information about a network port within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -19,7 +19,7 @@ from primaite.utils.validation.port import Port
_LOGGER = getLogger(__name__)
class NodesObservation(AbstractObservation, discriminator="NODES"):
class NodesObservation(AbstractObservation, discriminator="nodes"):
"""Nodes observation, provides status information about nodes within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -11,7 +11,7 @@ from pydantic import BaseModel, computed_field, ConfigDict, Field, model_validat
from primaite.game.agent.observations.observations import AbstractObservation, WhereType
class NestedObservation(AbstractObservation, discriminator="CUSTOM"):
class NestedObservation(AbstractObservation, discriminator="custom"):
"""Observation type that allows combining other observations into a gymnasium.spaces.Dict space."""
class NestedObservationItem(BaseModel):
@@ -48,7 +48,7 @@ class NestedObservation(AbstractObservation, discriminator="CUSTOM"):
def __init__(self, components: Dict[str, AbstractObservation]) -> None:
"""Initialise nested observation."""
self.components: Dict[str, AbstractObservation] = components
"""Maps label: observation object"""
"""Maps label observation object"""
self.default_observation = {label: obs.default_observation for label, obs in self.components.items()}
"""Default observation is just the default observations of constituents."""
@@ -84,7 +84,7 @@ class NestedObservation(AbstractObservation, discriminator="CUSTOM"):
```yaml
observation_space:
- type: CUSTOM
- type: custom
options:
components:
@@ -119,7 +119,7 @@ class NestedObservation(AbstractObservation, discriminator="CUSTOM"):
return cls(components=instances)
class NullObservation(AbstractObservation, discriminator="NONE"):
class NullObservation(AbstractObservation, discriminator="none"):
"""Empty observation that acts as a placeholder."""
def __init__(self) -> None:
@@ -157,7 +157,7 @@ class ObservationManager(BaseModel):
"""Config Schema for Observation Manager."""
model_config = ConfigDict(extra="forbid")
type: str = "NONE"
type: str = "none"
"""discriminator name for the top-level observation."""
options: AbstractObservation.ConfigSchema = Field(
default_factory=lambda: NullObservation.ConfigSchema(), validate_default=True
@@ -187,7 +187,7 @@ class ObservationManager(BaseModel):
return data
# (TODO: duplicate default definition between here and the actual model)
obs_type = data["type"] if "type" in data else "NONE"
obs_type = data["type"] if "type" in data else "none"
obs_class = AbstractObservation._registry[obs_type]
# if no options are passed in, try to create a default schema. Only works if there are no mandatory fields

View File

@@ -18,7 +18,7 @@ from primaite.utils.validation.port import Port
_LOGGER = getLogger(__name__)
class RouterObservation(AbstractObservation, discriminator="ROUTER"):
class RouterObservation(AbstractObservation, discriminator="router"):
"""Router observation, provides status information about a router within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -113,7 +113,7 @@ class RouterObservation(AbstractObservation, discriminator="ROUTER"):
if self.ports:
obs["PORTS"] = {i + 1: p.observe(state) for i, p in enumerate(self.ports)}
if self.include_users:
sess = router_state["services"]["UserSessionManager"]
sess = router_state["services"]["user-session-manager"]
obs["users"] = {
"local_login": 1 if sess["current_local_user"] else 0,
"remote_sessions": min(self.max_users, len(sess["active_remote_sessions"])),

View File

@@ -10,7 +10,7 @@ from primaite.game.agent.observations.observations import AbstractObservation, W
from primaite.game.agent.utils import access_from_nested_dict, NOT_PRESENT_IN_STATE
class ServiceObservation(AbstractObservation, discriminator="SERVICE"):
class ServiceObservation(AbstractObservation, discriminator="service"):
"""Service observation, shows status of a service in the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):
@@ -73,7 +73,7 @@ class ServiceObservation(AbstractObservation, discriminator="SERVICE"):
return cls(where=parent_where + ["services", config.service_name])
class ApplicationObservation(AbstractObservation, discriminator="APPLICATION"):
class ApplicationObservation(AbstractObservation, discriminator="application"):
"""Application observation, shows the status of an application within the simulation environment."""
class ConfigSchema(AbstractObservation.ConfigSchema):

View File

@@ -12,7 +12,7 @@ the structure:
```yaml
reward_function:
reward_components:
- type: DATABASE_FILE_INTEGRITY
- type: database-file-integrity
weight: 0.5
options:
node_name: database_server
@@ -20,7 +20,7 @@ the structure:
file_name: database.db
- type: WEB_SERVER_404_PENALTY
- type: web-server-404-penalty
weight: 0.5
options:
node_name: web_server
@@ -92,7 +92,7 @@ class AbstractReward(BaseModel):
return 0.0
class DummyReward(AbstractReward, discriminator="DUMMY"):
class DummyReward(AbstractReward, discriminator="dummy"):
"""Dummy reward function component which always returns 0.0."""
def calculate(self, state: Dict, last_action_response: "AgentHistoryItem") -> float:
@@ -108,7 +108,7 @@ class DummyReward(AbstractReward, discriminator="DUMMY"):
return 0.0
class DatabaseFileIntegrity(AbstractReward, discriminator="DATABASE_FILE_INTEGRITY"):
class DatabaseFileIntegrity(AbstractReward, discriminator="database-file-integrity"):
"""Reward function component which rewards the agent for maintaining the integrity of a database file."""
config: "DatabaseFileIntegrity.ConfigSchema"
@@ -118,7 +118,7 @@ class DatabaseFileIntegrity(AbstractReward, discriminator="DATABASE_FILE_INTEGRI
class ConfigSchema(AbstractReward.ConfigSchema):
"""ConfigSchema for DatabaseFileIntegrity."""
type: str = "DATABASE_FILE_INTEGRITY"
type: str = "database-file-integrity"
node_hostname: str
folder_name: str
file_name: str
@@ -161,7 +161,7 @@ class DatabaseFileIntegrity(AbstractReward, discriminator="DATABASE_FILE_INTEGRI
return 0
class WebServer404Penalty(AbstractReward, discriminator="WEB_SERVER_404_PENALTY"):
class WebServer404Penalty(AbstractReward, discriminator="web-server-404-penalty"):
"""Reward function component which penalises the agent when the web server returns a 404 error."""
config: "WebServer404Penalty.ConfigSchema"
@@ -171,7 +171,7 @@ class WebServer404Penalty(AbstractReward, discriminator="WEB_SERVER_404_PENALTY"
class ConfigSchema(AbstractReward.ConfigSchema):
"""ConfigSchema for WebServer404Penalty."""
type: str = "WEB_SERVER_404_PENALTY"
type: str = "web-server-404-penalty"
node_hostname: str
service_name: str
sticky: bool = True
@@ -215,7 +215,7 @@ class WebServer404Penalty(AbstractReward, discriminator="WEB_SERVER_404_PENALTY"
return self.reward
class WebpageUnavailablePenalty(AbstractReward, discriminator="WEBPAGE_UNAVAILABLE_PENALTY"):
class WebpageUnavailablePenalty(AbstractReward, discriminator="webpage-unavailable-penalty"):
"""Penalises the agent when the web browser fails to fetch a webpage."""
config: "WebpageUnavailablePenalty.ConfigSchema"
@@ -225,7 +225,7 @@ class WebpageUnavailablePenalty(AbstractReward, discriminator="WEBPAGE_UNAVAILAB
class ConfigSchema(AbstractReward.ConfigSchema):
"""ConfigSchema for WebpageUnavailablePenalty."""
type: str = "WEBPAGE_UNAVAILABLE_PENALTY"
type: str = "webpage-unavailable-penalty"
node_hostname: str = ""
sticky: bool = True
@@ -248,7 +248,7 @@ class WebpageUnavailablePenalty(AbstractReward, discriminator="WEBPAGE_UNAVAILAB
"nodes",
self.config.node_hostname,
"applications",
"WebBrowser",
"web-browser",
]
web_browser_state = access_from_nested_dict(state, self.location_in_state)
@@ -261,7 +261,7 @@ class WebpageUnavailablePenalty(AbstractReward, discriminator="WEBPAGE_UNAVAILAB
"node",
self.config.node_hostname,
"application",
"WebBrowser",
"web-browser",
"execute",
]
@@ -289,7 +289,7 @@ class WebpageUnavailablePenalty(AbstractReward, discriminator="WEBPAGE_UNAVAILAB
return self.reward
class GreenAdminDatabaseUnreachablePenalty(AbstractReward, discriminator="GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY"):
class GreenAdminDatabaseUnreachablePenalty(AbstractReward, discriminator="green-admin-database-unreachable-penalty"):
"""Penalises the agent when the green db clients fail to connect to the database."""
config: "GreenAdminDatabaseUnreachablePenalty.ConfigSchema"
@@ -298,7 +298,7 @@ class GreenAdminDatabaseUnreachablePenalty(AbstractReward, discriminator="GREEN_
class ConfigSchema(AbstractReward.ConfigSchema):
"""ConfigSchema for GreenAdminDatabaseUnreachablePenalty."""
type: str = "GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY"
type: str = "green-admin-database-unreachable-penalty"
node_hostname: str
sticky: bool = True
@@ -322,7 +322,7 @@ class GreenAdminDatabaseUnreachablePenalty(AbstractReward, discriminator="GREEN_
"node",
self.config.node_hostname,
"application",
"DatabaseClient",
"database-client",
"execute",
]
@@ -339,7 +339,7 @@ class GreenAdminDatabaseUnreachablePenalty(AbstractReward, discriminator="GREEN_
return self.reward
class SharedReward(AbstractReward, discriminator="SHARED_REWARD"):
class SharedReward(AbstractReward, discriminator="shared-reward"):
"""Adds another agent's reward to the overall reward."""
config: "SharedReward.ConfigSchema"
@@ -347,7 +347,7 @@ class SharedReward(AbstractReward, discriminator="SHARED_REWARD"):
class ConfigSchema(AbstractReward.ConfigSchema):
"""Config schema for SharedReward."""
type: str = "SHARED_REWARD"
type: str = "shared-reward"
agent_name: str
def default_callback(agent_name: str) -> Never:
@@ -376,17 +376,17 @@ class SharedReward(AbstractReward, discriminator="SHARED_REWARD"):
return self.callback(self.config.agent_name)
class ActionPenalty(AbstractReward, discriminator="ACTION_PENALTY"):
"""Apply a negative reward when taking any action except do_nothing."""
class ActionPenalty(AbstractReward, discriminator="action-penalty"):
"""Apply a negative reward when taking any action except do-nothing."""
config: "ActionPenalty.ConfigSchema"
class ConfigSchema(AbstractReward.ConfigSchema):
"""Config schema for ActionPenalty.
:param action_penalty: Reward to give agents for taking any action except do_nothing
:param action_penalty: Reward to give agents for taking any action except do-nothing
:type action_penalty: float
:param do_nothing_penalty: Reward to give agent for taking the do_nothing action
:param do_nothing_penalty: Reward to give agent for taking the do-nothing action
:type do_nothing_penalty: float
"""
@@ -403,7 +403,7 @@ class ActionPenalty(AbstractReward, discriminator="ACTION_PENALTY"):
:return: Reward value
:rtype: float
"""
if last_action_response.action == "do_nothing":
if last_action_response.action == "do-nothing":
return self.config.do_nothing_penalty
else:

View File

@@ -13,7 +13,7 @@ from primaite.game.agent.scripted_agents.random_agent import PeriodicAgent
__all__ = "AbstractTAPAgent"
class AbstractTAPAgent(PeriodicAgent, discriminator="AbstractTAP"):
class AbstractTAPAgent(PeriodicAgent, discriminator="abstract-tap"):
"""Base class for TAP agents to inherit from."""
config: "AbstractTAPAgent.ConfigSchema" = Field(default_factory=lambda: AbstractTAPAgent.ConfigSchema())
@@ -27,7 +27,7 @@ class AbstractTAPAgent(PeriodicAgent, discriminator="AbstractTAP"):
class ConfigSchema(PeriodicAgent.ConfigSchema):
"""Configuration schema for Abstract TAP agents."""
type: str = "AbstractTAP"
type: str = "abstract-tap"
agent_settings: AbstractTAPAgent.AgentSettingsSchema = Field(
default_factory=lambda: AbstractTAPAgent.AgentSettingsSchema()
)

View File

@@ -9,18 +9,18 @@ from primaite.game.agent.scripted_agents.random_agent import PeriodicAgent
__all__ = "DataManipulationAgent"
class DataManipulationAgent(PeriodicAgent, discriminator="RedDatabaseCorruptingAgent"):
class DataManipulationAgent(PeriodicAgent, discriminator="red-database-corrupting-agent"):
"""Agent that uses a DataManipulationBot to perform an SQL injection attack."""
class AgentSettingsSchema(PeriodicAgent.AgentSettingsSchema):
"""Schema for the `agent_settings` part of the agent config."""
target_application: str = "DataManipulationBot"
target_application: str = "data-manipulation-bot"
class ConfigSchema(PeriodicAgent.ConfigSchema):
"""Configuration Schema for DataManipulationAgent."""
type: str = "RedDatabaseCorruptingAgent"
type: str = "red-database-corrupting-agent"
agent_settings: "DataManipulationAgent.AgentSettingsSchema" = Field(
default_factory=lambda: DataManipulationAgent.AgentSettingsSchema()
)
@@ -43,13 +43,13 @@ class DataManipulationAgent(PeriodicAgent, discriminator="RedDatabaseCorruptingA
"""
if timestep < self.next_execution_timestep:
self.logger.debug(msg="Performing do nothing action")
return "do_nothing", {}
return "do-nothing", {}
self._set_next_execution_timestep(
timestep=timestep + self.config.agent_settings.frequency, variance=self.config.agent_settings.variance
)
self.logger.info(msg="Performing a data manipulation attack!")
return "node_application_execute", {
return "node-application-execute", {
"node_name": self.start_node,
"application_name": self.config.agent_settings.target_application,
}

View File

@@ -13,7 +13,7 @@ from primaite.game.agent.interface import AbstractScriptedAgent
__all__ = "ProbabilisticAgent"
class ProbabilisticAgent(AbstractScriptedAgent, discriminator="ProbabilisticAgent"):
class ProbabilisticAgent(AbstractScriptedAgent, discriminator="probabilistic-agent"):
"""Scripted agent which randomly samples its action space with prescribed probabilities for each action."""
rng: Generator = Field(default_factory=lambda: np.random.default_rng(np.random.randint(0, 65535)))
@@ -46,7 +46,7 @@ class ProbabilisticAgent(AbstractScriptedAgent, discriminator="ProbabilisticAgen
class ConfigSchema(AbstractScriptedAgent.ConfigSchema):
"""Configuration schema for Probabilistic Agent."""
type: str = "ProbabilisticAgent"
type: str = "probabilistic-agent"
agent_settings: "ProbabilisticAgent.AgentSettingsSchema" = Field(
default_factory=lambda: ProbabilisticAgent.AgentSettingsSchema()
)

View File

@@ -11,7 +11,7 @@ from primaite.game.agent.interface import AbstractScriptedAgent
__all__ = ("RandomAgent", "PeriodicAgent")
class RandomAgent(AbstractScriptedAgent, discriminator="RandomAgent"):
class RandomAgent(AbstractScriptedAgent, discriminator="random-agent"):
"""Agent that ignores its observation and acts completely at random."""
config: "RandomAgent.ConfigSchema" = Field(default_factory=lambda: RandomAgent.ConfigSchema())
@@ -19,7 +19,7 @@ class RandomAgent(AbstractScriptedAgent, discriminator="RandomAgent"):
class ConfigSchema(AbstractScriptedAgent.ConfigSchema):
"""Configuration Schema for Random Agents."""
type: str = "RandomAgent"
type: str = "random-agent"
def get_action(self) -> Tuple[str, Dict]:
"""Sample the action space randomly.
@@ -34,7 +34,7 @@ class RandomAgent(AbstractScriptedAgent, discriminator="RandomAgent"):
return self.action_manager.get_action(self.action_manager.space.sample())
class PeriodicAgent(AbstractScriptedAgent, discriminator="PeriodicAgent"):
class PeriodicAgent(AbstractScriptedAgent, discriminator="periodic-agent"):
"""Agent that does nothing most of the time, but executes application at regular intervals (with variance)."""
config: "PeriodicAgent.ConfigSchema" = Field(default_factory=lambda: PeriodicAgent.ConfigSchema())
@@ -72,7 +72,7 @@ class PeriodicAgent(AbstractScriptedAgent, discriminator="PeriodicAgent"):
class ConfigSchema(AbstractScriptedAgent.ConfigSchema):
"""Configuration Schema for Periodic Agent."""
type: str = "PeriodicAgent"
type: str = "periodic-agent"
"""Name of the agent."""
agent_settings: "PeriodicAgent.AgentSettingsSchema" = Field(
default_factory=lambda: PeriodicAgent.AgentSettingsSchema()
@@ -113,9 +113,9 @@ class PeriodicAgent(AbstractScriptedAgent, discriminator="PeriodicAgent"):
self._set_next_execution_timestep(
timestep + self.config.agent_settings.frequency, self.config.agent_settings.variance
)
return "node_application_execute", {
return "node-application-execute", {
"node_name": self.start_node,
"application_name": self.config.agent_settings.target_application,
}
return "do_nothing", {}
return "do-nothing", {}

View File

@@ -109,7 +109,7 @@
" - install\n",
" - RansomwareScript\n",
" 5:\n",
" action: c2_server_ransomware_configure\n",
" action: c2-server-ransomware-configure\n",
" options:\n",
" node_id: 1\n",
" config:\n",
@@ -416,7 +416,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Server Actions | c2_server_ransomware_configure\n",
"### **Command and Control** | C2 Server Actions | c2-server-ransomware-configure\n",
"\n",
"Another action the C2 Server grants is the ability for a Red Agent to configure the RansomwareScript via the C2 Server rather than the note directly.\n",
"\n",
@@ -435,7 +435,7 @@
" ...\n",
" action_map:\n",
" 5:\n",
" action: c2_server_ransomware_configure\n",
" action: c2-server-ransomware-configure\n",
" options:\n",
" node_id: 1\n",
" config:\n",

View File

@@ -244,7 +244,7 @@ class SimComponent(BaseModel):
..code::python
class WebBrowser(Application, discriminator="WebBrowser"):
class WebBrowser(Application, discriminator="web-browser"):
def _init_request_manager(self) -> RequestManager:
rm = super()._init_request_manager() # all requests generic to any Application get initialised
rm.add_request(...) # initialise any requests specific to the web browser

View File

@@ -130,8 +130,8 @@ class File(FileSystemItemABC):
Return False if corruption is detected, otherwise True
"""
warnings.warn("node_file_checkhash is currently not implemented.")
self.sys_log.warning("node_file_checkhash is currently not implemented.")
warnings.warn("node-file-checkhash is currently not implemented.")
self.sys_log.warning("node-file-checkhash is currently not implemented.")
return False
if self.deleted:

View File

@@ -396,8 +396,8 @@ class Folder(FileSystemItemABC):
Return False if corruption is detected, otherwise True
"""
warnings.warn("node_folder_checkhash is currently not implemented.")
self.sys_log.error("node_folder_checkhash is currently not implemented.")
warnings.warn("node-folder-checkhash is currently not implemented.")
self.sys_log.error("node-folder-checkhash is currently not implemented.")
return False
if self.deleted:

View File

@@ -22,7 +22,7 @@ class NetworkNodeAdder(BaseModel):
Here is a template that users can use to define custom node adders:
```
class YourNodeAdder(NetworkNodeAdder, discriminator="your_name"):
class YourNodeAdder(NetworkNodeAdder, discriminator="your-name"):
class ConfigSchema(NetworkNodeAdder.ConfigSchema):
property_1 : str
property_2 : int
@@ -99,13 +99,13 @@ class NetworkNodeAdder(BaseModel):
adder_class.add_nodes_to_net(config=adder_class.ConfigSchema(**config), network=network)
class OfficeLANAdder(NetworkNodeAdder, discriminator="office_lan"):
class OfficeLANAdder(NetworkNodeAdder, discriminator="office-lan"):
"""Creates an office LAN."""
class ConfigSchema(NetworkNodeAdder.ConfigSchema):
"""Configuration schema for OfficeLANAdder."""
type: Literal["office_lan"] = "office_lan"
type: Literal["office-lan"] = "office-lan"
lan_name: str
"""Name of lan used for generating hostnames for new nodes."""
subnet_base: int

View File

@@ -824,7 +824,7 @@ class User(SimComponent):
return self.model_dump()
class UserManager(Service, discriminator="UserManager"):
class UserManager(Service, discriminator="user-manager"):
"""
Manages users within the PrimAITE system, handling creation, authentication, and administration.
@@ -836,7 +836,7 @@ class UserManager(Service, discriminator="UserManager"):
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for UserManager."""
type: str = "UserManager"
type: str = "user-manager"
config: "UserManager.ConfigSchema" = Field(default_factory=lambda: UserManager.ConfigSchema())
@@ -849,7 +849,7 @@ class UserManager(Service, discriminator="UserManager"):
:param username: The username for the default admin user
:param password: The password for the default admin user
"""
kwargs["name"] = "UserManager"
kwargs["name"] = "user-manager"
kwargs["port"] = PORT_LOOKUP["NONE"]
kwargs["protocol"] = PROTOCOL_LOOKUP["NONE"]
super().__init__(**kwargs)
@@ -1037,7 +1037,7 @@ class UserManager(Service, discriminator="UserManager"):
@property
def _user_session_manager(self) -> "UserSessionManager":
return self.software_manager.software["UserSessionManager"] # noqa
return self.software_manager.software["user-session-manager"] # noqa
class UserSession(SimComponent):
@@ -1137,7 +1137,7 @@ class RemoteUserSession(UserSession):
return state
class UserSessionManager(Service, discriminator="UserSessionManager"):
class UserSessionManager(Service, discriminator="user-session-manager"):
"""
Manages user sessions on a Node, including local and remote sessions.
@@ -1147,7 +1147,7 @@ class UserSessionManager(Service, discriminator="UserSessionManager"):
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for UserSessionManager."""
type: str = "UserSessionManager"
type: str = "user-session-manager"
config: "UserSessionManager.ConfigSchema" = Field(default_factory=lambda: UserSessionManager.ConfigSchema())
@@ -1179,7 +1179,7 @@ class UserSessionManager(Service, discriminator="UserSessionManager"):
:param username: The username for the default admin user
:param password: The password for the default admin user
"""
kwargs["name"] = "UserSessionManager"
kwargs["name"] = "user-session-manager"
kwargs["port"] = PORT_LOOKUP["NONE"]
kwargs["protocol"] = PROTOCOL_LOOKUP["NONE"]
super().__init__(**kwargs)
@@ -1289,7 +1289,7 @@ class UserSessionManager(Service, discriminator="UserSessionManager"):
:return: The UserManager instance.
"""
return self.software_manager.software["UserManager"] # noqa
return self.software_manager.software["user-manager"] # noqa
def pre_timestep(self, timestep: int) -> None:
"""Apply any pre-timestep logic that helps make sure we have the correct observations."""
@@ -1608,17 +1608,17 @@ class Node(SimComponent, ABC):
@property
def user_manager(self) -> Optional[UserManager]:
"""The Nodes User Manager."""
return self.software_manager.software.get("UserManager") # noqa
return self.software_manager.software.get("user-manager") # noqa
@property
def user_session_manager(self) -> Optional[UserSessionManager]:
"""The Nodes User Session Manager."""
return self.software_manager.software.get("UserSessionManager") # noqa
return self.software_manager.software.get("user-session-manager") # noqa
@property
def terminal(self) -> Optional[Terminal]:
"""The Nodes Terminal."""
return self.software_manager.software.get("Terminal")
"""The Node's Terminal."""
return self.software_manager.software.get("terminal")
def local_login(self, username: str, password: str) -> Optional[str]:
"""

View File

@@ -33,6 +33,6 @@ class Computer(HostNode, discriminator="computer"):
* Web Browser
"""
SYSTEM_SOFTWARE: ClassVar[Dict] = {**HostNode.SYSTEM_SOFTWARE, "FTPClient": FTPClient}
SYSTEM_SOFTWARE: ClassVar[Dict] = {**HostNode.SYSTEM_SOFTWARE, "ftp-client": FTPClient}
pass

View File

@@ -262,7 +262,7 @@ class NIC(IPWiredNetworkInterface):
return f"Port {self.port_name if self.port_name else self.port_num}: {self.mac_address}/{self.ip_address}"
class HostNode(Node, discriminator="HostNode"):
class HostNode(Node, discriminator="host-node"):
"""
Represents a host node in the network.
@@ -309,14 +309,14 @@ class HostNode(Node, discriminator="HostNode"):
SYSTEM_SOFTWARE: ClassVar[Dict] = {
"HostARP": HostARP,
"ICMP": ICMP,
"DNSClient": DNSClient,
"NTPClient": NTPClient,
"WebBrowser": WebBrowser,
"NMAP": NMAP,
"UserSessionManager": UserSessionManager,
"UserManager": UserManager,
"Terminal": Terminal,
"icmp": ICMP,
"dns-client": DNSClient,
"ntp-client": NTPClient,
"web-browser": WebBrowser,
"nmap": NMAP,
"user-session-manager": UserSessionManager,
"user-manager": UserManager,
"terminal": Terminal,
}
"""List of system software that is automatically installed on nodes."""
@@ -337,7 +337,7 @@ class HostNode(Node, discriminator="HostNode"):
:return: NMAP application installed on the Node.
:rtype: Optional[NMAP]
"""
return self.software_manager.software.get("NMAP")
return self.software_manager.software.get("nmap")
@property
def arp(self) -> Optional[ARP]:
@@ -347,7 +347,7 @@ class HostNode(Node, discriminator="HostNode"):
:return: ARP Cache for given HostNode
:rtype: Optional[ARP]
"""
return self.software_manager.software.get("ARP")
return self.software_manager.software.get("arp")
def default_gateway_hello(self):
"""
@@ -379,8 +379,8 @@ class HostNode(Node, discriminator="HostNode"):
dst_port = frame.udp.dst_port
can_accept_nmap = False
if self.software_manager.software.get("NMAP"):
if self.software_manager.software["NMAP"].operating_state == ApplicationOperatingState.RUNNING:
if self.software_manager.software.get("nmap"):
if self.software_manager.software["nmap"].operating_state == ApplicationOperatingState.RUNNING:
can_accept_nmap = True
accept_nmap = can_accept_nmap and frame.payload.__class__.__name__ == "PortScanPayload"

View File

@@ -7,7 +7,7 @@ from primaite.simulator.network.transmission.data_link_layer import Frame
from primaite.simulator.system.services.arp.arp import ARP
class NetworkNode(Node, discriminator="NetworkNode"):
class NetworkNode(Node, discriminator="network-node"):
"""
Represents an abstract base class for a network node that can receive and process network frames.
@@ -40,4 +40,4 @@ class NetworkNode(Node, discriminator="NetworkNode"):
:return: ARP Cache for given NetworkNode
:rtype: Optional[ARP]
"""
return self.software_manager.software.get("ARP")
return self.software_manager.software.get("arp")

View File

@@ -91,7 +91,7 @@ class WirelessAccessPoint(IPWirelessNetworkInterface):
)
class WirelessRouter(Router, discriminator="wireless_router"):
class WirelessRouter(Router, discriminator="wireless-router"):
"""
A WirelessRouter class that extends the functionality of a standard Router to include wireless capabilities.

View File

@@ -160,7 +160,7 @@ def arcd_uc2_network() -> Network:
db_client_1: DatabaseClient = client_1.software_manager.software.get("DatabaseClient")
db_client_1.configure(server_ip_address=IPv4Address("192.168.1.14"))
db_client_1.run()
web_browser_1 = client_1.software_manager.software.get("WebBrowser")
web_browser_1 = client_1.software_manager.software.get("web-browser")
web_browser_1.target_url = "http://arcd.com/users/"
client_1.software_manager.install(DataManipulationBot)
db_manipulation_bot: DataManipulationBot = client_1.software_manager.software.get("DataManipulationBot")
@@ -182,10 +182,10 @@ def arcd_uc2_network() -> Network:
)
client_2.power_on()
client_2.software_manager.install(DatabaseClient)
db_client_2 = client_2.software_manager.software.get("DatabaseClient")
db_client_2 = client_2.software_manager.software.get("database-client")
db_client_2.configure(server_ip_address=IPv4Address("192.168.1.14"))
db_client_2.run()
web_browser_2 = client_2.software_manager.software.get("WebBrowser")
web_browser_2 = client_2.software_manager.software.get("web-browser")
web_browser_2.target_url = "http://arcd.com/users/"
network.connect(
endpoint_b=client_2.network_interface[1],
@@ -218,7 +218,7 @@ def arcd_uc2_network() -> Network:
network.connect(endpoint_b=database_server.network_interface[1], endpoint_a=switch_1.network_interface[3])
database_server.software_manager.install(DatabaseService)
database_service: DatabaseService = database_server.software_manager.software.get("DatabaseService") # noqa
database_service: DatabaseService = database_server.software_manager.software.get("database-service") # noqa
database_service.start()
database_service.configure_backup(backup_server=IPv4Address("192.168.1.16"))
@@ -234,7 +234,7 @@ def arcd_uc2_network() -> Network:
web_server.power_on()
web_server.software_manager.install(DatabaseClient)
database_client: DatabaseClient = web_server.software_manager.software.get("DatabaseClient")
database_client: DatabaseClient = web_server.software_manager.software.get("database-client")
database_client.configure(server_ip_address=IPv4Address("192.168.1.14"))
network.connect(endpoint_b=web_server.network_interface[1], endpoint_a=switch_1.network_interface[2])
database_client.run()
@@ -243,7 +243,7 @@ def arcd_uc2_network() -> Network:
web_server.software_manager.install(WebServer)
# register the web_server to a domain
dns_server_service: DNSServer = domain_controller.software_manager.software.get("DNSServer") # noqa
dns_server_service: DNSServer = domain_controller.software_manager.software.get("dns-server") # noqa
dns_server_service.dns_register("arcd.com", web_server.network_interface[1].ip_address)
# Backup Server

View File

@@ -38,8 +38,8 @@ class Simulation(SimComponent):
rm.add_request("network", RequestType(func=self.network._request_manager))
# pass through domain requests to the domain object
rm.add_request("domain", RequestType(func=self.domain._request_manager))
# if 'do_nothing' is requested, just return a success
rm.add_request("do_nothing", RequestType(func=lambda request, context: RequestResponse(status="success")))
# if 'do-nothing' is requested, just return a success
rm.add_request("do-nothing", RequestType(func=lambda request, context: RequestResponse(status="success")))
return rm
def describe_state(self) -> Dict:

View File

@@ -61,7 +61,7 @@ class DatabaseClientConnection(BaseModel):
return str(self)
class DatabaseClient(Application, discriminator="DatabaseClient"):
class DatabaseClient(Application, discriminator="database-client"):
"""
A DatabaseClient application.
@@ -72,7 +72,7 @@ class DatabaseClient(Application, discriminator="DatabaseClient"):
class ConfigSchema(Application.ConfigSchema):
"""ConfigSchema for DatabaseClient."""
type: str = "DatabaseClient"
type: str = "database-client"
db_server_ip: Optional[IPV4Address] = None
server_password: Optional[str] = None
@@ -97,7 +97,7 @@ class DatabaseClient(Application, discriminator="DatabaseClient"):
"""Native Client Connection for using the client directly (similar to psql in a terminal)."""
def __init__(self, **kwargs):
kwargs["name"] = "DatabaseClient"
kwargs["name"] = "database-client"
kwargs["port"] = PORT_LOOKUP["POSTGRES_SERVER"]
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
super().__init__(**kwargs)

View File

@@ -44,7 +44,7 @@ class PortScanPayload(SimComponent):
return state
class NMAP(Application, discriminator="NMAP"):
class NMAP(Application, discriminator="nmap"):
"""
A class representing the NMAP application for network scanning.
@@ -55,7 +55,7 @@ class NMAP(Application, discriminator="NMAP"):
class ConfigSchema(Application.ConfigSchema):
"""ConfigSchema for NMAP."""
type: str = "NMAP"
type: str = "nmap"
config: "NMAP.ConfigSchema" = Field(default_factory=lambda: NMAP.ConfigSchema())

View File

@@ -162,11 +162,11 @@ class AbstractC2(Application):
:return: An FTPClient object is successful, else None
:rtype: union[FTPClient, None]
"""
ftp_client: Union[FTPClient, None] = self.software_manager.software.get("FTPClient")
ftp_client: Union[FTPClient, None] = self.software_manager.software.get("ftp-client")
if ftp_client is None:
self.sys_log.warning(f"{self.__class__.__name__}: No FTPClient. Attempting to install.")
self.software_manager.install(FTPClient)
ftp_client = self.software_manager.software.get("FTPClient")
ftp_client = self.software_manager.software.get("ftp-client")
# Force start if the service is stopped.
if ftp_client.operating_state == ServiceOperatingState.STOPPED:
@@ -189,11 +189,11 @@ class AbstractC2(Application):
:return: An FTPServer object is successful, else None
:rtype: Optional[FTPServer]
"""
ftp_server: Optional[FTPServer] = self.software_manager.software.get("FTPServer")
ftp_server: Optional[FTPServer] = self.software_manager.software.get("ftp-server")
if ftp_server is None:
self.sys_log.warning(f"{self.__class__.__name__}:No FTPServer installed. Attempting to install FTPServer.")
self.software_manager.install(FTPServer)
ftp_server = self.software_manager.software.get("FTPServer")
ftp_server = self.software_manager.software.get("ftp-server")
# Force start if the service is stopped.
if ftp_server.operating_state == ServiceOperatingState.STOPPED:

View File

@@ -17,7 +17,7 @@ from primaite.utils.validation.ipv4_address import IPV4Address
from primaite.utils.validation.port import Port, PORT_LOOKUP
class C2Beacon(AbstractC2, discriminator="C2Beacon"):
class C2Beacon(AbstractC2, discriminator="c2-beacon"):
"""
C2 Beacon Application.
@@ -39,7 +39,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
class ConfigSchema(AbstractC2.ConfigSchema):
"""ConfigSchema for C2Beacon."""
type: str = "C2Beacon"
type: str = "c2-beacon"
c2_server_ip_address: Optional[IPV4Address] = None
keep_alive_frequency: int = 5
masquerade_protocol: IPProtocol = PROTOCOL_LOOKUP["TCP"]
@@ -54,13 +54,13 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
"The currently in use terminal session."
def __init__(self, **kwargs):
kwargs["name"] = "C2Beacon"
kwargs["name"] = "c2-beacon"
super().__init__(**kwargs)
@property
def _host_terminal(self) -> Optional[Terminal]:
"""Return the Terminal that is installed on the same machine as the C2 Beacon."""
host_terminal: Terminal = self.software_manager.software.get("Terminal")
"""Return the terminal that is installed on the same machine as the C2 Beacon."""
host_terminal: Terminal = self.software_manager.software.get("terminal")
if host_terminal is None:
self.sys_log.warning(f"{self.__class__.__name__} cannot find a terminal on its host.")
return host_terminal
@@ -68,7 +68,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
@property
def _host_ransomware_script(self) -> RansomwareScript:
"""Return the RansomwareScript that is installed on the same machine as the C2 Beacon."""
ransomware_script: RansomwareScript = self.software_manager.software.get("RansomwareScript")
ransomware_script: RansomwareScript = self.software_manager.software.get("ransomware-script")
if ransomware_script is None:
self.sys_log.warning(f"{self.__class__.__name__} cannot find installed ransomware on its host.")
return ransomware_script
@@ -300,7 +300,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
:payload C2Packet: The incoming INPUT command.
:type Masquerade Packet: C2Packet.
:return: Returns the Request Response returned by the Terminal execute method.
:return: Returns the Request Response returned by the terminal execute method.
:rtype: Request Response
"""
command_opts = RansomwareOpts.model_validate(payload.payload)
@@ -324,7 +324,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
:payload C2Packet: The incoming INPUT command.
:type Masquerade Packet: C2Packet.
:return: Returns the Request Response returned by the Terminal execute method.
:return: Returns the Request Response returned by the terminal execute method.
:rtype: Request Response
"""
if self._host_ransomware_script is None:
@@ -351,7 +351,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
:payload C2Packet: The incoming INPUT command.
:type Masquerade Packet: C2Packet.
:return: Returns a tuple containing Request Response returned by the Terminal execute method.
:return: Returns a tuple containing Request Response returned by the terminal execute method.
:rtype: Request Response
"""
if self._host_ftp_server is None:
@@ -372,7 +372,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
)
# Using the terminal to start the FTP Client on the remote machine.
self.terminal_session.execute(command=["service", "start", "FTPClient"])
self.terminal_session.execute(command=["service", "start", "ftp-client"])
# Need to supply to the FTP Client the C2 Beacon's host IP.
host_network_interfaces = self.software_manager.node.network_interfaces
@@ -430,7 +430,7 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
# Using the terminal to send the target data back to the C2 Beacon.
exfil_response: RequestResponse = RequestResponse.from_bool(
self.terminal_session.execute(command=["service", "FTPClient", "send", ftp_opts])
self.terminal_session.execute(command=["service", "ftp-client", "send", ftp_opts])
)
# Validating that we successfully received the target data.
@@ -472,14 +472,14 @@ class C2Beacon(AbstractC2, discriminator="C2Beacon"):
def _command_terminal(self, payload: C2Packet) -> RequestResponse:
"""
C2 Command: Terminal.
C2 Command: terminal.
Creates a request that executes a terminal command.
This request is then sent to the terminal service in order to be executed.
:payload C2Packet: The incoming INPUT command.
:type Masquerade Packet: C2Packet.
:return: Returns the Request Response returned by the Terminal execute method.
:return: Returns the Request Response returned by the terminal execute method.
:rtype: Request Response
"""
command_opts = TerminalOpts.model_validate(payload.payload)

View File

@@ -16,7 +16,7 @@ from primaite.simulator.system.applications.red_applications.c2 import (
from primaite.simulator.system.applications.red_applications.c2.abstract_c2 import AbstractC2, C2Command, C2Payload
class C2Server(AbstractC2, discriminator="C2Server"):
class C2Server(AbstractC2, discriminator="c2-server"):
"""
C2 Server Application.
@@ -37,7 +37,7 @@ class C2Server(AbstractC2, discriminator="C2Server"):
class ConfigSchema(AbstractC2.ConfigSchema):
"""ConfigSchema for C2Server."""
type: str = "C2Server"
type: str = "c2-server"
config: ConfigSchema = Field(default_factory=lambda: C2Server.ConfigSchema())
@@ -125,7 +125,7 @@ class C2Server(AbstractC2, discriminator="C2Server"):
return rm
def __init__(self, **kwargs):
kwargs["name"] = "C2Server"
kwargs["name"] = "c2-server"
super().__init__(**kwargs)
self.run()

View File

@@ -40,13 +40,13 @@ class DataManipulationAttackStage(IntEnum):
"Signifies that the attack has failed."
class DataManipulationBot(Application, discriminator="DataManipulationBot"):
class DataManipulationBot(Application, discriminator="data-manipulation-bot"):
"""A bot that simulates a script which performs a SQL injection attack."""
class ConfigSchema(Application.ConfigSchema):
"""Configuration schema for DataManipulationBot."""
type: str = "DataManipulationBot"
type: str = "data-manipulation-bot"
server_ip: Optional[IPV4Address] = None
server_password: Optional[str] = None
payload: str = "DELETE"
@@ -64,7 +64,7 @@ class DataManipulationBot(Application, discriminator="DataManipulationBot"):
"Whether to repeat attacking once finished."
def __init__(self, **kwargs):
kwargs["name"] = "DataManipulationBot"
kwargs["name"] = "data-manipulation-bot"
kwargs["port"] = PORT_LOOKUP["NONE"]
kwargs["protocol"] = PROTOCOL_LOOKUP["NONE"]
@@ -92,7 +92,7 @@ class DataManipulationBot(Application, discriminator="DataManipulationBot"):
@property
def _host_db_client(self) -> DatabaseClient:
"""Return the database client that is installed on the same machine as the DataManipulationBot."""
db_client = self.software_manager.software.get("DatabaseClient")
db_client = self.software_manager.software.get("database-client")
if db_client is None:
self.sys_log.warning(f"{self.__class__.__name__} cannot find a database client on its host.")
return db_client

View File

@@ -32,13 +32,13 @@ class DoSAttackStage(IntEnum):
"Attack is completed."
class DoSBot(DatabaseClient, discriminator="DoSBot"):
class DoSBot(DatabaseClient, discriminator="dos-bot"):
"""A bot that simulates a Denial of Service attack."""
class ConfigSchema(DatabaseClient.ConfigSchema):
"""ConfigSchema for DoSBot."""
type: str = "DoSBot"
type: str = "dos-bot"
target_ip_address: Optional[IPV4Address] = None
target_port: Port = PORT_LOOKUP["POSTGRES_SERVER"]
payload: Optional[str] = None
@@ -72,7 +72,7 @@ class DoSBot(DatabaseClient, discriminator="DoSBot"):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.name = "DoSBot"
self.name = "dos-bot"
self.target_ip_address = self.config.target_ip_address
self.target_port = self.config.target_port
self.payload = self.config.payload

View File

@@ -14,7 +14,7 @@ from primaite.utils.validation.ipv4_address import IPV4Address
from primaite.utils.validation.port import PORT_LOOKUP
class RansomwareScript(Application, discriminator="RansomwareScript"):
class RansomwareScript(Application, discriminator="ransomware-script"):
"""Ransomware Kill Chain - Designed to be used by the TAP001 Agent on the example layout Network.
:ivar payload: The attack stage query payload. (Default ENCRYPT)
@@ -23,7 +23,7 @@ class RansomwareScript(Application, discriminator="RansomwareScript"):
class ConfigSchema(Application.ConfigSchema):
"""ConfigSchema for RansomwareScript."""
type: str = "RansomwareScript"
type: str = "ransomware-script"
server_ip: Optional[IPV4Address] = None
server_password: Optional[str] = None
payload: str = "ENCRYPT"
@@ -38,7 +38,7 @@ class RansomwareScript(Application, discriminator="RansomwareScript"):
"Payload String for the payload stage"
def __init__(self, **kwargs):
kwargs["name"] = "RansomwareScript"
kwargs["name"] = "ransomware-script"
kwargs["port"] = PORT_LOOKUP["NONE"]
kwargs["protocol"] = PROTOCOL_LOOKUP["NONE"]
@@ -63,7 +63,7 @@ class RansomwareScript(Application, discriminator="RansomwareScript"):
@property
def _host_db_client(self) -> DatabaseClient:
"""Return the database client that is installed on the same machine as the Ransomware Script."""
db_client: DatabaseClient = self.software_manager.software.get("DatabaseClient")
db_client: DatabaseClient = self.software_manager.software.get("database-client")
if db_client is None:
self.sys_log.warning(f"{self.__class__.__name__} cannot find a database client on its host.")
return db_client

View File

@@ -23,7 +23,7 @@ from primaite.utils.validation.port import Port, PORT_LOOKUP
_LOGGER = getLogger(__name__)
class WebBrowser(Application, discriminator="WebBrowser"):
class WebBrowser(Application, discriminator="web-browser"):
"""
Represents a web browser in the simulation environment.
@@ -33,7 +33,7 @@ class WebBrowser(Application, discriminator="WebBrowser"):
class ConfigSchema(Application.ConfigSchema):
"""ConfigSchema for WebBrowser."""
type: str = "WebBrowser"
type: str = "web-browser"
target_url: Optional[str] = None
config: "WebBrowser.ConfigSchema" = Field(default_factory=lambda: WebBrowser.ConfigSchema())
@@ -48,7 +48,7 @@ class WebBrowser(Application, discriminator="WebBrowser"):
"""Keep a log of visited websites and information about the visit, such as response code."""
def __init__(self, **kwargs):
kwargs["name"] = "WebBrowser"
kwargs["name"] = "web-browser"
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
# default for web is port 80
if kwargs.get("port") is None:
@@ -108,7 +108,7 @@ class WebBrowser(Application, discriminator="WebBrowser"):
return False
# get the IP address of the domain name via DNS
dns_client: DNSClient = self.software_manager.software.get("DNSClient")
dns_client: DNSClient = self.software_manager.software.get("dns-client")
domain_exists = dns_client.check_domain_exists(target_domain=parsed_url.hostname)
# if domain does not exist, the request fails

View File

@@ -60,12 +60,12 @@ class SoftwareManager:
@property
def arp(self) -> "ARP":
"""Provides access to the ARP service instance, if installed."""
return self.software.get("ARP") # noqa
return self.software.get("arp") # noqa
@property
def icmp(self) -> "ICMP":
"""Provides access to the ICMP service instance, if installed."""
return self.software.get("ICMP") # noqa
return self.software.get("icmp") # noqa
def get_open_ports(self) -> List[Port]:
"""
@@ -243,7 +243,7 @@ class SoftwareManager:
:param session: The transport session the payload originates from.
"""
if payload.__class__.__name__ == "PortScanPayload":
self.software.get("NMAP").receive(payload=payload, session_id=session_id)
self.software.get("nmap").receive(payload=payload, session_id=session_id)
return
main_receiver = self.port_protocol_mapping.get((port, protocol), None)
if main_receiver:

View File

@@ -15,7 +15,7 @@ from primaite.utils.validation.ipv4_address import IPV4Address
from primaite.utils.validation.port import PORT_LOOKUP
class ARP(Service, discriminator="ARP"):
class ARP(Service, discriminator="arp"):
"""
The ARP (Address Resolution Protocol) Service.
@@ -26,7 +26,7 @@ class ARP(Service, discriminator="ARP"):
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for ARP."""
type: str = "ARP"
type: str = "arp"
config: "ARP.ConfigSchema" = Field(default_factory=lambda: ARP.ConfigSchema())

View File

@@ -19,7 +19,7 @@ from primaite.utils.validation.port import PORT_LOOKUP
_LOGGER = getLogger(__name__)
class DatabaseService(Service, discriminator="DatabaseService"):
class DatabaseService(Service, discriminator="database-service"):
"""
A class for simulating a generic SQL Server service.
@@ -29,11 +29,11 @@ class DatabaseService(Service, discriminator="DatabaseService"):
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for DatabaseService."""
type: str = "DatabaseService"
type: str = "database-service"
backup_server_ip: Optional[IPv4Address] = None
db_password: Optional[str] = None
config: "DatabaseService.ConfigSchema" = Field(default_factory=lambda: DatabaseService.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: DatabaseService.ConfigSchema())
backup_server_ip: IPv4Address = None
"""IP address of the backup server."""
@@ -45,7 +45,7 @@ class DatabaseService(Service, discriminator="DatabaseService"):
"""File name of latest backup."""
def __init__(self, **kwargs):
kwargs["name"] = "DatabaseService"
kwargs["name"] = "database-service"
kwargs["port"] = PORT_LOOKUP["POSTGRES_SERVER"]
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
super().__init__(**kwargs)
@@ -69,7 +69,7 @@ class DatabaseService(Service, discriminator="DatabaseService"):
"""
super().install()
if not self.parent.software_manager.software.get("FTPClient"):
if not self.parent.software_manager.software.get("ftp-client"):
self.parent.sys_log.info(f"{self.name}: Installing FTPClient to enable database backups")
self.parent.software_manager.install(FTPClient)
@@ -93,7 +93,7 @@ class DatabaseService(Service, discriminator="DatabaseService"):
return False
software_manager: SoftwareManager = self.software_manager
ftp_client_service: FTPClient = software_manager.software.get("FTPClient")
ftp_client_service: FTPClient = software_manager.software.get("ftp-client")
if not ftp_client_service:
self.sys_log.error(
@@ -127,7 +127,7 @@ class DatabaseService(Service, discriminator="DatabaseService"):
return False
software_manager: SoftwareManager = self.software_manager
ftp_client_service: FTPClient = software_manager.software.get("FTPClient")
ftp_client_service: FTPClient = software_manager.software.get("ftp-client")
if not ftp_client_service:
self.sys_log.error(

View File

@@ -18,21 +18,21 @@ if TYPE_CHECKING:
_LOGGER = getLogger(__name__)
class DNSClient(Service, discriminator="DNSClient"):
class DNSClient(Service, discriminator="dns-client"):
"""Represents a DNS Client as a Service."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for DNSClient."""
type: str = "DNSClient"
type: str = "dns-client"
dns_server: Optional[IPV4Address] = None
config: "DNSClient.ConfigSchema" = Field(default_factory=lambda: DNSClient.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: DNSClient.ConfigSchema())
dns_cache: Dict[str, IPv4Address] = {}
"A dict of known mappings between domain/URLs names and IPv4 addresses."
def __init__(self, **kwargs):
kwargs["name"] = "DNSClient"
kwargs["name"] = "dns-client"
kwargs["port"] = PORT_LOOKUP["DNS"]
# DNS uses UDP by default
# it switches to TCP when the bytes exceed 512 (or 4096) bytes

View File

@@ -14,22 +14,22 @@ from primaite.utils.validation.port import PORT_LOOKUP
_LOGGER = getLogger(__name__)
class DNSServer(Service, discriminator="DNSServer"):
class DNSServer(Service, discriminator="dns-server"):
"""Represents a DNS Server as a Service."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for DNSServer."""
type: str = "DNSServer"
type: str = "dns-server"
domain_mapping: dict = {}
config: "DNSServer.ConfigSchema" = Field(default_factory=lambda: DNSServer.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: DNSServer.ConfigSchema())
dns_table: Dict[str, IPv4Address] = {}
"A dict of mappings between domain names and IPv4 addresses."
def __init__(self, **kwargs):
kwargs["name"] = "DNSServer"
kwargs["name"] = "dns-server"
kwargs["port"] = PORT_LOOKUP["DNS"]
# DNS uses UDP by default
# it switches to TCP when the bytes exceed 512 (or 4096) bytes

View File

@@ -18,7 +18,7 @@ from primaite.utils.validation.port import Port, PORT_LOOKUP
_LOGGER = getLogger(__name__)
class FTPClient(FTPServiceABC, discriminator="FTPClient"):
class FTPClient(FTPServiceABC, discriminator="ftp-client"):
"""
A class for simulating an FTP client service.
@@ -26,15 +26,15 @@ class FTPClient(FTPServiceABC, discriminator="FTPClient"):
RFC 959: https://datatracker.ietf.org/doc/html/rfc959
"""
config: "FTPClient.ConfigSchema" = Field(default_factory=lambda: FTPClient.ConfigSchema())
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for FTPClient."""
type: str = "FTPClient"
type: str = "ftp-client"
config: ConfigSchema = Field(default_factory=lambda: FTPClient.ConfigSchema())
def __init__(self, **kwargs):
kwargs["name"] = "FTPClient"
kwargs["name"] = "ftp-client"
kwargs["port"] = PORT_LOOKUP["FTP"]
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
super().__init__(**kwargs)

View File

@@ -12,7 +12,7 @@ from primaite.utils.validation.port import is_valid_port, PORT_LOOKUP
_LOGGER = getLogger(__name__)
class FTPServer(FTPServiceABC, discriminator="FTPServer"):
class FTPServer(FTPServiceABC, discriminator="ftp-server"):
"""
A class for simulating an FTP server service.
@@ -20,17 +20,18 @@ class FTPServer(FTPServiceABC, discriminator="FTPServer"):
RFC 959: https://datatracker.ietf.org/doc/html/rfc959
"""
config: "FTPServer.ConfigSchema" = Field(default_factory=lambda: FTPServer.ConfigSchema())
server_password: Optional[str] = None
class ConfigSchema(FTPServiceABC.ConfigSchema):
"""ConfigSchema for FTPServer."""
type: str = "FTPServer"
type: str = "ftp-server"
server_password: Optional[str] = None
config: ConfigSchema = Field(default_factory=lambda: FTPServer.ConfigSchema())
def __init__(self, **kwargs):
kwargs["name"] = "FTPServer"
kwargs["name"] = "ftp-server"
kwargs["port"] = PORT_LOOKUP["FTP"]
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
super().__init__(**kwargs)

View File

@@ -16,7 +16,7 @@ from primaite.utils.validation.port import PORT_LOOKUP
_LOGGER = getLogger(__name__)
class ICMP(Service, discriminator="ICMP"):
class ICMP(Service, discriminator="icmp"):
"""
The Internet Control Message Protocol (ICMP) service.
@@ -27,14 +27,14 @@ class ICMP(Service, discriminator="ICMP"):
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for ICMP."""
type: str = "ICMP"
type: str = "icmp"
config: "ICMP.ConfigSchema" = Field(default_factory=lambda: ICMP.ConfigSchema())
request_replies: Dict = {}
def __init__(self, **kwargs):
kwargs["name"] = "ICMP"
kwargs["name"] = "icmp"
kwargs["port"] = PORT_LOOKUP["NONE"]
kwargs["protocol"] = PROTOCOL_LOOKUP["ICMP"]
super().__init__(**kwargs)

View File

@@ -1,13 +1,13 @@
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
# class RouterICMP(ICMP):
# class RouterICMP(icmp):
# """
# A class to represent a router's Internet Control Message Protocol (ICMP) handler.
# A class to represent a router's Internet Control Message Protocol (icmp) handler.
#
# :param sys_log: System log for logging network events and errors.
# :type sys_log: SysLog
# :param arp_cache: The ARP cache for resolving MAC addresses.
# :param arp_cache: The arp cache for resolving MAC addresses.
# :type arp_cache: ARPCache
# :param router: The router to which this ICMP handler belongs.
# :param router: The router to which this icmp handler belongs.
# :type router: Router
# """
#
@@ -19,7 +19,7 @@
#
# def process_icmp(self, frame: Frame, from_network_interface: NIC, is_reattempt: bool = False):
# """
# Process incoming ICMP frames based on ICMP type.
# Process incoming icmp frames based on icmp type.
#
# :param frame: The incoming frame to process.
# :param from_network_interface: The network interface where the frame is coming from.
@@ -36,13 +36,13 @@
# self.sys_log.info(f"Received echo request from {frame.ip.src_ip_address}")
# target_mac_address = self.arp.get_arp_cache_mac_address(frame.ip.src_ip_address)
# src_nic = self.arp.get_arp_cache_network_interface(frame.ip.src_ip_address)
# tcp_header = TCPHeader(src_port=Port["ARP"], dst_port=Port["ARP"])
# tcp_header = TCPHeader(src_port=Port["arp"], dst_port=Port["arp"])
#
# # Network Layer
# ip_packet = IPPacket(
# src_ip_address=network_interface.ip_address,
# dst_ip_address=frame.ip.src_ip_address,
# protocol=IPProtocol["ICMP"],
# protocol=IPProtocol["icmp"],
# )
# # Data Link Layer
# ethernet_header = EthernetHeader(
@@ -54,7 +54,7 @@
# identifier=frame.icmp.identifier,
# sequence=frame.icmp.sequence + 1,
# )
# payload = secrets.token_urlsafe(int(32 / 1.3)) # Standard ICMP 32 bytes size
# payload = secrets.token_urlsafe(int(32 / 1.3)) # Standard icmp 32 bytes size
# frame = Frame(
# ethernet=ethernet_header,
# ip=ip_packet,

View File

@@ -15,23 +15,23 @@ from primaite.utils.validation.port import Port, PORT_LOOKUP
_LOGGER = getLogger(__name__)
class NTPClient(Service, discriminator="NTPClient"):
class NTPClient(Service, discriminator="ntp-client"):
"""Represents a NTP client as a service."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for NTPClient."""
type: str = "NTPClient"
type: str = "ntp-client"
ntp_server_ip: Optional[IPV4Address] = None
config: "NTPClient.ConfigSchema" = Field(default_factory=lambda: NTPClient.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: NTPClient.ConfigSchema())
ntp_server: Optional[IPv4Address] = None
"The NTP server the client sends requests to."
time: Optional[datetime] = None
def __init__(self, **kwargs):
kwargs["name"] = "NTPClient"
kwargs["name"] = "ntp-client"
kwargs["port"] = PORT_LOOKUP["NTP"]
kwargs["protocol"] = PROTOCOL_LOOKUP["UDP"]
super().__init__(**kwargs)

View File

@@ -13,18 +13,18 @@ from primaite.utils.validation.port import PORT_LOOKUP
_LOGGER = getLogger(__name__)
class NTPServer(Service, discriminator="NTPServer"):
class NTPServer(Service, discriminator="ntp-server"):
"""Represents a NTP server as a service."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for NTPServer."""
type: str = "NTPServer"
type: str = "ntp-server"
config: "NTPServer.ConfigSchema" = Field(default_factory=lambda: NTPServer.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: NTPServer.ConfigSchema())
def __init__(self, **kwargs):
kwargs["name"] = "NTPServer"
kwargs["name"] = "ntp-server"
kwargs["port"] = PORT_LOOKUP["NTP"]
kwargs["protocol"] = PROTOCOL_LOOKUP["UDP"]
super().__init__(**kwargs)

View File

@@ -129,13 +129,13 @@ class RemoteTerminalConnection(TerminalClientConnection):
return self.parent_terminal.send(payload=payload, session_id=self.ssh_session_id)
class Terminal(Service, discriminator="Terminal"):
class Terminal(Service, discriminator="terminal"):
"""Class used to simulate a generic terminal service. Can be interacted with by other terminals via SSH."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for Terminal."""
type: str = "Terminal"
type: str = "terminal"
config: "Terminal.ConfigSchema" = Field(default_factory=lambda: Terminal.ConfigSchema())
@@ -143,7 +143,7 @@ class Terminal(Service, discriminator="Terminal"):
"""Dictionary of connect requests made to remote nodes."""
def __init__(self, **kwargs):
kwargs["name"] = "Terminal"
kwargs["name"] = "terminal"
kwargs["port"] = PORT_LOOKUP["SSH"]
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
super().__init__(**kwargs)
@@ -186,7 +186,7 @@ class Terminal(Service, discriminator="Terminal"):
return RequestResponse(status="failure", data={})
rm.add_request(
"node_session_remote_login",
"node-session-remote-login",
request_type=RequestType(func=_remote_login),
)

View File

@@ -21,15 +21,15 @@ from primaite.utils.validation.port import Port, PORT_LOOKUP
_LOGGER = getLogger(__name__)
class WebServer(Service, discriminator="WebServer"):
class WebServer(Service, discriminator="web-server"):
"""Class used to represent a Web Server Service in simulation."""
class ConfigSchema(Service.ConfigSchema):
"""ConfigSchema for WebServer."""
type: str = "WebServer"
type: str = "web-server"
config: "WebServer.ConfigSchema" = Field(default_factory=lambda: WebServer.ConfigSchema())
config: ConfigSchema = Field(default_factory=lambda: WebServer.ConfigSchema())
response_codes_this_timestep: List[HttpStatusCode] = []
@@ -57,7 +57,7 @@ class WebServer(Service, discriminator="WebServer"):
return super().pre_timestep(timestep)
def __init__(self, **kwargs):
kwargs["name"] = "WebServer"
kwargs["name"] = "web-server"
kwargs["protocol"] = PROTOCOL_LOOKUP["TCP"]
# default for web is port 80
if kwargs.get("port") is None:
@@ -146,7 +146,7 @@ class WebServer(Service, discriminator="WebServer"):
def _establish_db_connection(self) -> None:
"""Establish a connection to db."""
db_client = self.software_manager.software.get("DatabaseClient")
db_client = self.software_manager.software.get("database-client")
self.db_connection: DatabaseClientConnection = db_client.get_new_connection()
def send(