#2059: apply suggestions from PR + adding another test that checks for dos affecting green agent

This commit is contained in:
Czar Echavez
2023-12-13 11:56:25 +00:00
parent f0be77c79b
commit 592e1a3610
4 changed files with 81 additions and 4 deletions

View File

@@ -49,7 +49,7 @@ class DoSBot(DatabaseClient, Application):
port_scan_p_of_success: float = 0.1 port_scan_p_of_success: float = 0.1
"""Probability of port scanning being sucessful.""" """Probability of port scanning being sucessful."""
dos_intensity: float = 1 dos_intensity: float = 1.0
"""How much of the max sessions will be used by the DoS when attacking.""" """How much of the max sessions will be used by the DoS when attacking."""
def __init__(self, **kwargs): def __init__(self, **kwargs):
@@ -92,7 +92,7 @@ class DoSBot(DatabaseClient, Application):
payload: Optional[str] = None, payload: Optional[str] = None,
repeat: bool = False, repeat: bool = False,
port_scan_p_of_success: float = 0.1, port_scan_p_of_success: float = 0.1,
dos_intensity: float = 1, dos_intensity: float = 1.0,
max_sessions: int = 1000, max_sessions: int = 1000,
): ):
""" """

View File

@@ -143,6 +143,10 @@ class DatabaseService(Service):
status_code = 500 # Default internal server error status_code = 500 # Default internal server error
if self.operating_state == ServiceOperatingState.RUNNING: if self.operating_state == ServiceOperatingState.RUNNING:
status_code = 503 # service unavailable status_code = 503 # service unavailable
if self.health_state_actual == SoftwareHealthState.OVERWHELMED:
self.sys_log.error(
f"{self.name}: Connect request for {connection_id=} declined. Service is at capacity."
)
if self.health_state_actual == SoftwareHealthState.GOOD: if self.health_state_actual == SoftwareHealthState.GOOD:
if self.password == password: if self.password == password:
status_code = 200 # ok status_code = 200 # ok

View File

@@ -58,7 +58,7 @@ class Service(IOSoftware):
if not super()._can_perform_action(): if not super()._can_perform_action():
return False return False
if self.operating_state is not self.operating_state.RUNNING: if self.operating_state is not ServiceOperatingState.RUNNING:
# service is not running # service is not running
_LOGGER.error(f"Cannot perform action: {self.name} is {self.operating_state.name}") _LOGGER.error(f"Cannot perform action: {self.name} is {self.operating_state.name}")
return False return False

View File

@@ -3,10 +3,13 @@ from typing import Tuple
import pytest import pytest
from primaite.simulator.network.container import Network
from primaite.simulator.network.hardware.nodes.computer import Computer from primaite.simulator.network.hardware.nodes.computer import Computer
from primaite.simulator.network.hardware.nodes.router import ACLAction, Router
from primaite.simulator.network.hardware.nodes.server import Server from primaite.simulator.network.hardware.nodes.server import Server
from primaite.simulator.network.transmission.transport_layer import Port from primaite.simulator.network.transmission.transport_layer import Port
from primaite.simulator.system.applications.application import ApplicationOperatingState from primaite.simulator.system.applications.application import ApplicationOperatingState
from primaite.simulator.system.applications.database_client import DatabaseClient
from primaite.simulator.system.applications.red_applications.dos_bot import DoSAttackStage, DoSBot from primaite.simulator.system.applications.red_applications.dos_bot import DoSAttackStage, DoSBot
from primaite.simulator.system.services.database.database_service import DatabaseService from primaite.simulator.system.services.database.database_service import DatabaseService
from primaite.simulator.system.software import SoftwareHealthState from primaite.simulator.system.software import SoftwareHealthState
@@ -25,7 +28,7 @@ def dos_bot_and_db_server(client_server) -> Tuple[DoSBot, Computer, DatabaseServ
target_port=Port.POSTGRES_SERVER, target_port=Port.POSTGRES_SERVER,
) )
# Install FTP Server service on server # Install DB Server service on server
server.software_manager.install(DatabaseService) server.software_manager.install(DatabaseService)
db_server_service: DatabaseService = server.software_manager.software.get("DatabaseService") db_server_service: DatabaseService = server.software_manager.software.get("DatabaseService")
db_server_service.start() db_server_service.start()
@@ -33,6 +36,43 @@ def dos_bot_and_db_server(client_server) -> Tuple[DoSBot, Computer, DatabaseServ
return dos_bot, computer, db_server_service, server return dos_bot, computer, db_server_service, server
@pytest.fixture(scope="function")
def dos_bot_db_server_green_client(example_network) -> Network:
network: Network = example_network
router_1: Router = example_network.get_node_by_hostname("router_1")
router_1.acl.add_rule(
action=ACLAction.PERMIT, src_port=Port.POSTGRES_SERVER, dst_port=Port.POSTGRES_SERVER, position=0
)
client_1: Computer = network.get_node_by_hostname("client_1")
client_2: Computer = network.get_node_by_hostname("client_2")
server: Server = network.get_node_by_hostname("server_1")
# install DoS bot on client 1
client_1.software_manager.install(DoSBot)
dos_bot: DoSBot = client_1.software_manager.software.get("DoSBot")
dos_bot.configure(
target_ip_address=IPv4Address(server.nics.get(next(iter(server.nics))).ip_address),
target_port=Port.POSTGRES_SERVER,
)
# install db server service on server
server.software_manager.install(DatabaseService)
db_server_service: DatabaseService = server.software_manager.software.get("DatabaseService")
db_server_service.start()
# Install DB client (green) on client 2
client_2.software_manager.install(DatabaseClient)
database_client: DatabaseClient = client_2.software_manager.software.get("DatabaseClient")
database_client.configure(server_ip_address=IPv4Address("192.168.0.1"))
database_client.run()
return network
def test_repeating_dos_attack(dos_bot_and_db_server): def test_repeating_dos_attack(dos_bot_and_db_server):
dos_bot, computer, db_server_service, server = dos_bot_and_db_server dos_bot, computer, db_server_service, server = dos_bot_and_db_server
@@ -105,3 +145,36 @@ def test_dos_bot_database_service_connection(dos_bot_and_db_server):
assert len(dos_bot.connections) == db_server_service.max_sessions assert len(dos_bot.connections) == db_server_service.max_sessions
assert len(db_server_service.connections) == db_server_service.max_sessions assert len(db_server_service.connections) == db_server_service.max_sessions
assert len(dos_bot.connections) == db_server_service.max_sessions assert len(dos_bot.connections) == db_server_service.max_sessions
def test_dos_blocks_green_agent_connection(dos_bot_db_server_green_client):
network: Network = dos_bot_db_server_green_client
client_1: Computer = network.get_node_by_hostname("client_1")
dos_bot: DoSBot = client_1.software_manager.software.get("DoSBot")
client_2: Computer = network.get_node_by_hostname("client_2")
green_db_client: DatabaseClient = client_2.software_manager.software.get("DatabaseClient")
server: Server = network.get_node_by_hostname("server_1")
db_server_service: DatabaseService = server.software_manager.software.get("DatabaseService")
assert db_server_service.health_state_actual is SoftwareHealthState.GOOD
dos_bot.port_scan_p_of_success = 1
dos_bot.repeat = False
dos_bot.run()
# DoS bot fills up connection of db server service
assert len(dos_bot.connections) == db_server_service.max_sessions
assert len(db_server_service.connections) == db_server_service.max_sessions
assert len(dos_bot.connections) == db_server_service.max_sessions
assert len(green_db_client.connections) == 0
assert dos_bot.attack_stage is DoSAttackStage.COMPLETED
# db server service is overwhelmed
assert db_server_service.health_state_actual is SoftwareHealthState.OVERWHELMED
# green agent tries to connect but fails because service is overwhelmed
assert green_db_client.connect() is False
assert len(green_db_client.connections) == 0