#2059: apply suggestions from PR + adding another test that checks for dos affecting green agent
This commit is contained in:
@@ -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,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user