From 304dfbd21f4d173ac344688f4e2b5f5d89ed1b55 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 18:26:18 +0000 Subject: [PATCH 01/30] Island: Add callable to handle PingScanEvent --- .../agent_event_handlers/handle_scan_data.py | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py new file mode 100644 index 000000000..8e75860a8 --- /dev/null +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py @@ -0,0 +1,56 @@ +from ipaddress import IPv4Address +from logging import getLogger + +from common.agent_events import PingScanEvent +from monkey_island.cc.models import CommunicationType, Machine +from monkey_island.cc.repository import ( + IAgentRepository, + IMachineRepository, + INodeRepository, + RetrievalError, + UnknownRecordError, +) + +logger = getLogger(__name__) + + +class handle_scan_data: + def __init__( + self, + agent_repository: IAgentRepository, + machine_repository: IMachineRepository, + node_repository: INodeRepository, + ): + self._agent_repository = agent_repository + self._machine_repository = machine_repository + self._node_repository = node_repository + + def __call__(self, event: PingScanEvent): + try: + # Get or create the destination machine + # NOTE: Assuming IP's are unique for now + if not isinstance(event.target, IPv4Address): + logger.error("Unable to process scan data: Unknown target") + return + dest_machines = self._machine_repository.get_machines_by_ip(event.target) + if not dest_machines: + machine = Machine(id=self._machine_repository.get_new_id()) + dest_machines = [machine] + self._machine_repository.upsert_machine(machine) + + # Update the destination machine + dest_machine = dest_machines[0] + if event.scan_data.os is not None: + dest_machine.operating_system = event.scan_data.os + self._machine_repository.upsert_machine(dest_machine) + + # Get the source machine + agent = self._agent_repository.get_agent_by_id(event.source) + src_machine = self._machine_repository.get_machine_by_id(agent.machine_id) + + # Update or create the node + self._node_repository.upsert_communication( + src_machine.id, dest_machine.id, CommunicationType.SCANNED + ) + except (RetrievalError, UnknownRecordError) as err: + logger.error(f"Unable to process scan data: {err}") From eacd42696931e466bb132a75e60ed6bbfd04ed1d Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 18:42:06 +0000 Subject: [PATCH 02/30] Island: Handle StorageError in handle_scan_data --- .../monkey_island/cc/agent_event_handlers/handle_scan_data.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py index 8e75860a8..b3c7eee2b 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py @@ -8,6 +8,7 @@ from monkey_island.cc.repository import ( IMachineRepository, INodeRepository, RetrievalError, + StorageError, UnknownRecordError, ) @@ -52,5 +53,5 @@ class handle_scan_data: self._node_repository.upsert_communication( src_machine.id, dest_machine.id, CommunicationType.SCANNED ) - except (RetrievalError, UnknownRecordError) as err: + except (RetrievalError, StorageError, UnknownRecordError) as err: logger.error(f"Unable to process scan data: {err}") From 89c6e2b7bc062f7f15082d93934809e59a175f7f Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 18:58:13 +0000 Subject: [PATCH 03/30] Island: Extract methods in handle_scan_data --- .../agent_event_handlers/handle_scan_data.py | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py index b3c7eee2b..b3a44085b 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py @@ -28,30 +28,34 @@ class handle_scan_data: def __call__(self, event: PingScanEvent): try: - # Get or create the destination machine - # NOTE: Assuming IP's are unique for now - if not isinstance(event.target, IPv4Address): - logger.error("Unable to process scan data: Unknown target") - return - dest_machines = self._machine_repository.get_machines_by_ip(event.target) - if not dest_machines: - machine = Machine(id=self._machine_repository.get_new_id()) - dest_machines = [machine] - self._machine_repository.upsert_machine(machine) - - # Update the destination machine - dest_machine = dest_machines[0] - if event.scan_data.os is not None: - dest_machine.operating_system = event.scan_data.os - self._machine_repository.upsert_machine(dest_machine) - - # Get the source machine - agent = self._agent_repository.get_agent_by_id(event.source) - src_machine = self._machine_repository.get_machine_by_id(agent.machine_id) + dest_machine = self._get_destination_machine(event) + self._update_destination_machine(dest_machine, event) + src_machine = self._get_source_machine(event) # Update or create the node self._node_repository.upsert_communication( src_machine.id, dest_machine.id, CommunicationType.SCANNED ) - except (RetrievalError, StorageError, UnknownRecordError) as err: + except (RetrievalError, StorageError, TypeError, UnknownRecordError) as err: logger.error(f"Unable to process scan data: {err}") + + def _get_destination_machine(self, event: PingScanEvent) -> Machine: + # NOTE: Assuming IP's are unique for now + if not isinstance(event.target, IPv4Address): + raise TypeError("Unknown target") + dest_machines = self._machine_repository.get_machines_by_ip(event.target) + if not dest_machines: + machine = Machine(id=self._machine_repository.get_new_id()) + dest_machines = [machine] + self._machine_repository.upsert_machine(machine) + + return dest_machines[0] + + def _get_source_machine(self, event: PingScanEvent) -> Machine: + agent = self._agent_repository.get_agent_by_id(event.source) + return self._machine_repository.get_machine_by_id(agent.machine_id) + + def _update_destination_machine(self, machine: Machine, event: PingScanEvent): + if event.scan_data.os is not None: + machine.operating_system = event.scan_data.os + self._machine_repository.upsert_machine(machine) From 371ca12dfbbea51b806e61b6ca5ccb896fb58ce4 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 19:23:21 +0000 Subject: [PATCH 04/30] Island: Add handle_scan_data to __init__.py --- monkey/monkey_island/cc/agent_event_handlers/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/monkey_island/cc/agent_event_handlers/__init__.py b/monkey/monkey_island/cc/agent_event_handlers/__init__.py index 755f52bd2..ed47c29af 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/agent_event_handlers/__init__.py @@ -1,2 +1,3 @@ +from .handle_scan_data import handle_scan_data from .save_event_to_event_repository import save_event_to_event_repository from .save_stolen_credentials_to_repository import save_stolen_credentials_to_repository From a0d6565c4a2bc0dd91aca671bdebbead879b9210 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 19:24:10 +0000 Subject: [PATCH 05/30] UT: Stub out unit tests for handle_scan_data --- .../test_handle_scan_data.py | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py new file mode 100644 index 000000000..1b9afc71b --- /dev/null +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -0,0 +1,66 @@ +from itertools import count +from unittest.mock import MagicMock +from uuid import UUID + +import pytest + +from common.agent_events import PingScanEvent +from common.types import PingScanData +from monkey_island.cc.agent_event_handlers import handle_scan_data +from monkey_island.cc.repository import ( + IAgentRepository, + IMachineRepository, + INodeRepository, + RetrievalError, + StorageError, + UnknownRecordError, +) + +SEED_ID = 99 + + +@pytest.fixture +def agent_repository() -> IAgentRepository: + agent_repository = MagicMock(spec=IAgentRepository) + agent_repository.upsert_agent = MagicMock() + return agent_repository + + +@pytest.fixture +def machine_repository() -> IMachineRepository: + machine_repository = MagicMock(spec=IMachineRepository) + machine_repository.get_new_id = MagicMock(side_effect=count(SEED_ID)) + machine_repository.upsert_machine = MagicMock() + return machine_repository + + +@pytest.fixture +def node_repository() -> INodeRepository: + node_repository = MagicMock(spec=INodeRepository) + node_repository.upsert_communication = MagicMock() + return node_repository + + +@pytest.fixture +def handler() -> handle_scan_data: + return handle_scan_data(agent_repository, machine_repository, node_repository) + + +def test_handle_scan_data__upserts_machine(handler: handle_scan_data): + pass + + +def test_handle_scan_data__upserts_node(handler: handle_scan_data): + pass + + +def test_handle_scan_data__node_not_upserted_if_no_matching_agent(handler: handle_scan_data): + pass + + +def test_handle_scan_data__node_not_upserted_if_no_matching_machine(handler: handle_scan_data): + pass + + +def test_handle_scan_data__upserts_machine_if_did_not_exist(handler: handle_scan_data): + pass From 1c127781ca5d055e211e07aae4622cb95f65c499 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 19:53:10 +0000 Subject: [PATCH 06/30] UT: Implement test_handle_scan_data__upserts_machine --- .../test_handle_scan_data.py | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index 1b9afc71b..08555edc1 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -1,12 +1,15 @@ +from ipaddress import IPv4Address, IPv4Interface from itertools import count from unittest.mock import MagicMock from uuid import UUID import pytest +from common import OperatingSystem from common.agent_events import PingScanEvent -from common.types import PingScanData +from common.types import PingScanData, SocketAddress from monkey_island.cc.agent_event_handlers import handle_scan_data +from monkey_island.cc.models import Agent, CommunicationType, Machine from monkey_island.cc.repository import ( IAgentRepository, IMachineRepository, @@ -17,12 +20,27 @@ from monkey_island.cc.repository import ( ) SEED_ID = 99 +AGENT_ID = UUID("1d8ce743-a0f4-45c5-96af-91106529d3e2") +MACHINE_ID = 11 +CC_SERVER = SocketAddress(ip="10.10.10.100", port="5000") +AGENT = Agent(id=AGENT_ID, machine_id=MACHINE_ID, start_time=0, parent_id=None, cc_server=CC_SERVER) +MACHINE = Machine( + id=MACHINE_ID, + hardware_id=5, + network_interfaces=[IPv4Interface("10.10.10.99/24")], +) +STORED_MACHINE = Machine( + id=33, + hardware_id=9, + network_interfaces=[IPv4Interface("10.10.10.1/24")], +) @pytest.fixture def agent_repository() -> IAgentRepository: agent_repository = MagicMock(spec=IAgentRepository) agent_repository.upsert_agent = MagicMock() + agent_repository.get_agent_by_id = MagicMock(return_value=AGENT) return agent_repository @@ -42,12 +60,30 @@ def node_repository() -> INodeRepository: @pytest.fixture -def handler() -> handle_scan_data: +def handler(agent_repository, machine_repository, node_repository) -> handle_scan_data: return handle_scan_data(agent_repository, machine_repository, node_repository) -def test_handle_scan_data__upserts_machine(handler: handle_scan_data): - pass +def test_handle_scan_data__upserts_machine( + handler: handle_scan_data, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + event = PingScanEvent( + source=AGENT_ID, + target=IPv4Address("10.10.10.1"), + scan_data=PingScanData(True, OperatingSystem.LINUX), + ) + machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + handler(event) + + expected_machine = STORED_MACHINE.copy() + expected_machine.operating_system = OperatingSystem.LINUX + + assert machine_repository.upsert_machine.called_with(expected_machine) + assert node_repository.upsert_communication.called_with( + MACHINE.id, expected_machine.id, CommunicationType.SCANNED + ) def test_handle_scan_data__upserts_node(handler: handle_scan_data): From ab32daa0e00c18ede0530b70745aaff9b0c2810a Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 20:50:15 +0000 Subject: [PATCH 07/30] Common: Fix AbstractAgentEvent union --- monkey/common/agent_events/abstract_agent_event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/common/agent_events/abstract_agent_event.py b/monkey/common/agent_events/abstract_agent_event.py index 8c3655602..e4469cae8 100644 --- a/monkey/common/agent_events/abstract_agent_event.py +++ b/monkey/common/agent_events/abstract_agent_event.py @@ -25,6 +25,6 @@ class AbstractAgentEvent(InfectionMonkeyBaseModel, ABC): """ source: AgentID - target: Union[MachineID, IPv4Address, None] = Field(default=None) + target: Union[IPv4Address, MachineID, None] = Field(default=None) timestamp: float = Field(default_factory=time.time) tags: FrozenSet[str] = Field(default_factory=frozenset) From ce8219aa6d9fc92525c6f0077328289d3af01c3b Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 20:53:56 +0000 Subject: [PATCH 08/30] UT: Implement test_handle_scan_data__upserts_node --- .../test_handle_scan_data.py | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index 08555edc1..a339a208b 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -81,13 +81,24 @@ def test_handle_scan_data__upserts_machine( expected_machine.operating_system = OperatingSystem.LINUX assert machine_repository.upsert_machine.called_with(expected_machine) - assert node_repository.upsert_communication.called_with( - MACHINE.id, expected_machine.id, CommunicationType.SCANNED + + +def test_handle_scan_data__upserts_node( + handler: handle_scan_data, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + event = PingScanEvent( + source=AGENT_ID, + target=IPv4Address("10.10.10.1"), + scan_data=PingScanData(True, OperatingSystem.LINUX), ) + machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + handler(event) - -def test_handle_scan_data__upserts_node(handler: handle_scan_data): - pass + assert node_repository.upsert_communication.called_with( + MACHINE.id, STORED_MACHINE.id, CommunicationType.SCANNED + ) def test_handle_scan_data__node_not_upserted_if_no_matching_agent(handler: handle_scan_data): From 18ca84a247e04b05004b3c2539e64c3660a32757 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 21:01:48 +0000 Subject: [PATCH 09/30] UT: Implement test_handle_scan_data__node_not_upserted_if_no_matching_agent --- .../test_handle_scan_data.py | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index a339a208b..66349656a 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -34,6 +34,11 @@ STORED_MACHINE = Machine( hardware_id=9, network_interfaces=[IPv4Interface("10.10.10.1/24")], ) +EVENT = PingScanEvent( + source=AGENT_ID, + target=IPv4Address("10.10.10.1"), + scan_data=PingScanData(True, OperatingSystem.LINUX), +) @pytest.fixture @@ -67,15 +72,9 @@ def handler(agent_repository, machine_repository, node_repository) -> handle_sca def test_handle_scan_data__upserts_machine( handler: handle_scan_data, machine_repository: IMachineRepository, - node_repository: INodeRepository, ): - event = PingScanEvent( - source=AGENT_ID, - target=IPv4Address("10.10.10.1"), - scan_data=PingScanData(True, OperatingSystem.LINUX), - ) machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) - handler(event) + handler(EVENT) expected_machine = STORED_MACHINE.copy() expected_machine.operating_system = OperatingSystem.LINUX @@ -88,21 +87,26 @@ def test_handle_scan_data__upserts_node( machine_repository: IMachineRepository, node_repository: INodeRepository, ): - event = PingScanEvent( - source=AGENT_ID, - target=IPv4Address("10.10.10.1"), - scan_data=PingScanData(True, OperatingSystem.LINUX), - ) machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) - handler(event) + handler(EVENT) assert node_repository.upsert_communication.called_with( MACHINE.id, STORED_MACHINE.id, CommunicationType.SCANNED ) -def test_handle_scan_data__node_not_upserted_if_no_matching_agent(handler: handle_scan_data): - pass +def test_handle_scan_data__node_not_upserted_if_no_matching_agent( + handler: handle_scan_data, + agent_repository: IAgentRepository, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + agent_repository.get_agent_by_id = MagicMock(side_effect=UnknownRecordError) + machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + + handler(EVENT) + + assert not node_repository.upsert_communication.called def test_handle_scan_data__node_not_upserted_if_no_matching_machine(handler: handle_scan_data): From 29355e9d14de0a8551d6a34908ce8afe52f6ebc9 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 21:04:42 +0000 Subject: [PATCH 10/30] UT: Implement test_handle_scan_data__node_not_upserted_if_no_matching_machine --- .../cc/agent_event_handlers/test_handle_scan_data.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index 66349656a..1309c33f8 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -109,8 +109,16 @@ def test_handle_scan_data__node_not_upserted_if_no_matching_agent( assert not node_repository.upsert_communication.called -def test_handle_scan_data__node_not_upserted_if_no_matching_machine(handler: handle_scan_data): - pass +def test_handle_scan_data__node_not_upserted_if_no_matching_machine( + handler: handle_scan_data, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + machine_repository.get_machine_by_id = MagicMock(side_effect=UnknownRecordError) + + handler(EVENT) + + assert not node_repository.upsert_communication.called def test_handle_scan_data__upserts_machine_if_did_not_exist(handler: handle_scan_data): From 799f08e3835b0efe0b23d6cda780d4f8bdee2ae3 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Tue, 27 Sep 2022 21:21:29 +0000 Subject: [PATCH 11/30] UT: Implement test_handle_scan_data__upserts_machine_if_not_existed --- .../test_handle_scan_data.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index 1309c33f8..60b65f8a2 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -69,11 +69,18 @@ def handler(agent_repository, machine_repository, node_repository) -> handle_sca return handle_scan_data(agent_repository, machine_repository, node_repository) +machines = {MACHINE_ID: MACHINE, STORED_MACHINE.id: STORED_MACHINE} + + +def machine_from_id(id: int): + return machines[id] + + def test_handle_scan_data__upserts_machine( handler: handle_scan_data, machine_repository: IMachineRepository, ): - machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) handler(EVENT) expected_machine = STORED_MACHINE.copy() @@ -121,5 +128,12 @@ def test_handle_scan_data__node_not_upserted_if_no_matching_machine( assert not node_repository.upsert_communication.called -def test_handle_scan_data__upserts_machine_if_did_not_exist(handler: handle_scan_data): - pass +def test_handle_scan_data__upserts_machine_if_not_existed( + handler: handle_scan_data, machine_repository: IMachineRepository +): + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + handler(EVENT) + + expected_machine = Machine(id=SEED_ID, operating_system=OperatingSystem.LINUX) + + assert machine_repository.upsert_machine.called_with(expected_machine) From ecb7ca0d8d48eddd38461a065e9c54bda3ffc41a Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 28 Sep 2022 12:10:39 +0300 Subject: [PATCH 12/30] Island: Subscribe ping scan events --- .../cc/setup/agent_event_handlers.py | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/monkey/monkey_island/cc/setup/agent_event_handlers.py b/monkey/monkey_island/cc/setup/agent_event_handlers.py index b01392361..4d61a5610 100644 --- a/monkey/monkey_island/cc/setup/agent_event_handlers.py +++ b/monkey/monkey_island/cc/setup/agent_event_handlers.py @@ -1,11 +1,18 @@ from common import DIContainer -from common.agent_events import CredentialsStolenEvent +from common.agent_events import CredentialsStolenEvent, PingScanEvent from common.event_queue import IAgentEventQueue from monkey_island.cc.agent_event_handlers import ( + handle_scan_data, save_event_to_event_repository, save_stolen_credentials_to_repository, ) -from monkey_island.cc.repository import IAgentEventRepository, ICredentialsRepository +from monkey_island.cc.repository import ( + IAgentEventRepository, + IAgentRepository, + ICredentialsRepository, + IMachineRepository, + INodeRepository, +) def setup_agent_event_handlers(container: DIContainer): @@ -22,3 +29,16 @@ def _subscribe_and_store_to_event_repository(container: DIContainer): container.resolve(ICredentialsRepository) ) agent_event_queue.subscribe_type(CredentialsStolenEvent, save_stolen_credentials_subscriber) + + +def _subscribe_ping_scan_event(container: DIContainer): + # Mypy don't handle cases where abstract class is passed as Type[...] + # https://github.com/python/mypy/issues/4717 + agent_event_queue = container.resolve(IAgentEventQueue) # type: ignore + agent_repository = container.resolve(IAgentRepository) # type: ignore + machine_repository = container.resolve(IMachineRepository) # type: ignore + node_repository = container.resolve(INodeRepository) # type: ignore + + handler = handle_scan_data(agent_repository, machine_repository, node_repository) + + agent_event_queue.subscribe_type(PingScanEvent, handler) From c807f97d1810a7733884f978851fe20ca358718e Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 28 Sep 2022 12:17:31 +0300 Subject: [PATCH 13/30] Island: Rename handle_scan_data to handle_ping_scan_event --- .../cc/agent_event_handlers/__init__.py | 2 +- ...le_scan_data.py => handle_ping_scan_event.py} | 2 +- .../cc/setup/agent_event_handlers.py | 4 ++-- .../test_handle_scan_data.py | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) rename monkey/monkey_island/cc/agent_event_handlers/{handle_scan_data.py => handle_ping_scan_event.py} (98%) diff --git a/monkey/monkey_island/cc/agent_event_handlers/__init__.py b/monkey/monkey_island/cc/agent_event_handlers/__init__.py index ed47c29af..1c7e4714c 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/agent_event_handlers/__init__.py @@ -1,3 +1,3 @@ -from .handle_scan_data import handle_scan_data +from .handle_ping_scan_event import handle_ping_scan_event from .save_event_to_event_repository import save_event_to_event_repository from .save_stolen_credentials_to_repository import save_stolen_credentials_to_repository diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py similarity index 98% rename from monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py rename to monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index b3a44085b..d7d46a2f3 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_scan_data.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -15,7 +15,7 @@ from monkey_island.cc.repository import ( logger = getLogger(__name__) -class handle_scan_data: +class handle_ping_scan_event: def __init__( self, agent_repository: IAgentRepository, diff --git a/monkey/monkey_island/cc/setup/agent_event_handlers.py b/monkey/monkey_island/cc/setup/agent_event_handlers.py index 4d61a5610..44861d766 100644 --- a/monkey/monkey_island/cc/setup/agent_event_handlers.py +++ b/monkey/monkey_island/cc/setup/agent_event_handlers.py @@ -2,7 +2,7 @@ from common import DIContainer from common.agent_events import CredentialsStolenEvent, PingScanEvent from common.event_queue import IAgentEventQueue from monkey_island.cc.agent_event_handlers import ( - handle_scan_data, + handle_ping_scan_event, save_event_to_event_repository, save_stolen_credentials_to_repository, ) @@ -39,6 +39,6 @@ def _subscribe_ping_scan_event(container: DIContainer): machine_repository = container.resolve(IMachineRepository) # type: ignore node_repository = container.resolve(INodeRepository) # type: ignore - handler = handle_scan_data(agent_repository, machine_repository, node_repository) + handler = handle_ping_scan_event(agent_repository, machine_repository, node_repository) agent_event_queue.subscribe_type(PingScanEvent, handler) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py index 60b65f8a2..5b4040f57 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py @@ -8,7 +8,7 @@ import pytest from common import OperatingSystem from common.agent_events import PingScanEvent from common.types import PingScanData, SocketAddress -from monkey_island.cc.agent_event_handlers import handle_scan_data +from monkey_island.cc.agent_event_handlers import handle_ping_scan_event from monkey_island.cc.models import Agent, CommunicationType, Machine from monkey_island.cc.repository import ( IAgentRepository, @@ -65,8 +65,8 @@ def node_repository() -> INodeRepository: @pytest.fixture -def handler(agent_repository, machine_repository, node_repository) -> handle_scan_data: - return handle_scan_data(agent_repository, machine_repository, node_repository) +def handler(agent_repository, machine_repository, node_repository) -> handle_ping_scan_event: + return handle_ping_scan_event(agent_repository, machine_repository, node_repository) machines = {MACHINE_ID: MACHINE, STORED_MACHINE.id: STORED_MACHINE} @@ -77,7 +77,7 @@ def machine_from_id(id: int): def test_handle_scan_data__upserts_machine( - handler: handle_scan_data, + handler: handle_ping_scan_event, machine_repository: IMachineRepository, ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) @@ -90,7 +90,7 @@ def test_handle_scan_data__upserts_machine( def test_handle_scan_data__upserts_node( - handler: handle_scan_data, + handler: handle_ping_scan_event, machine_repository: IMachineRepository, node_repository: INodeRepository, ): @@ -103,7 +103,7 @@ def test_handle_scan_data__upserts_node( def test_handle_scan_data__node_not_upserted_if_no_matching_agent( - handler: handle_scan_data, + handler: handle_ping_scan_event, agent_repository: IAgentRepository, machine_repository: IMachineRepository, node_repository: INodeRepository, @@ -117,7 +117,7 @@ def test_handle_scan_data__node_not_upserted_if_no_matching_agent( def test_handle_scan_data__node_not_upserted_if_no_matching_machine( - handler: handle_scan_data, + handler: handle_ping_scan_event, machine_repository: IMachineRepository, node_repository: INodeRepository, ): @@ -129,7 +129,7 @@ def test_handle_scan_data__node_not_upserted_if_no_matching_machine( def test_handle_scan_data__upserts_machine_if_not_existed( - handler: handle_scan_data, machine_repository: IMachineRepository + handler: handle_ping_scan_event, machine_repository: IMachineRepository ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) handler(EVENT) From b6d9f88deed749220754c448db3e000036664899 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 28 Sep 2022 18:03:25 +0300 Subject: [PATCH 14/30] Island: Style improvements in handle_ping_scan_event.py --- .../cc/agent_event_handlers/handle_ping_scan_event.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index d7d46a2f3..52fc34ddc 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -1,4 +1,3 @@ -from ipaddress import IPv4Address from logging import getLogger from common.agent_events import PingScanEvent @@ -36,13 +35,10 @@ class handle_ping_scan_event: self._node_repository.upsert_communication( src_machine.id, dest_machine.id, CommunicationType.SCANNED ) - except (RetrievalError, StorageError, TypeError, UnknownRecordError) as err: - logger.error(f"Unable to process scan data: {err}") + except (RetrievalError, StorageError, TypeError, UnknownRecordError): + logger.exception("Unable to process ping scan data") def _get_destination_machine(self, event: PingScanEvent) -> Machine: - # NOTE: Assuming IP's are unique for now - if not isinstance(event.target, IPv4Address): - raise TypeError("Unknown target") dest_machines = self._machine_repository.get_machines_by_ip(event.target) if not dest_machines: machine = Machine(id=self._machine_repository.get_new_id()) From 168a5845fd4291edd4336d022770967dcd6ca39f Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 28 Sep 2022 18:04:10 +0300 Subject: [PATCH 15/30] UT: Fix and rename unit tests in test_handle_ping_scan_event.py --- ...data.py => test_handle_ping_scan_event.py} | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) rename monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/{test_handle_scan_data.py => test_handle_ping_scan_event.py} (74%) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py similarity index 74% rename from monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py rename to monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index 5b4040f57..171266ae3 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_scan_data.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -14,8 +14,6 @@ from monkey_island.cc.repository import ( IAgentRepository, IMachineRepository, INodeRepository, - RetrievalError, - StorageError, UnknownRecordError, ) @@ -24,12 +22,12 @@ AGENT_ID = UUID("1d8ce743-a0f4-45c5-96af-91106529d3e2") MACHINE_ID = 11 CC_SERVER = SocketAddress(ip="10.10.10.100", port="5000") AGENT = Agent(id=AGENT_ID, machine_id=MACHINE_ID, start_time=0, parent_id=None, cc_server=CC_SERVER) -MACHINE = Machine( +PINGER_MACHINE = Machine( id=MACHINE_ID, hardware_id=5, network_interfaces=[IPv4Interface("10.10.10.99/24")], ) -STORED_MACHINE = Machine( +TARGET_MACHINE = Machine( id=33, hardware_id=9, network_interfaces=[IPv4Interface("10.10.10.1/24")], @@ -69,54 +67,67 @@ def handler(agent_repository, machine_repository, node_repository) -> handle_pin return handle_ping_scan_event(agent_repository, machine_repository, node_repository) -machines = {MACHINE_ID: MACHINE, STORED_MACHINE.id: STORED_MACHINE} +machines = {MACHINE_ID: PINGER_MACHINE, TARGET_MACHINE.id: TARGET_MACHINE} def machine_from_id(id: int): return machines[id] -def test_handle_scan_data__upserts_machine( +def test_handle_ping_scan_event__upserts_machine( handler: handle_ping_scan_event, machine_repository: IMachineRepository, ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) handler(EVENT) - expected_machine = STORED_MACHINE.copy() + expected_machine = TARGET_MACHINE.copy() expected_machine.operating_system = OperatingSystem.LINUX - assert machine_repository.upsert_machine.called_with(expected_machine) + machine_repository.upsert_machine.assert_called_with(expected_machine) -def test_handle_scan_data__upserts_node( +def test_handle_ping_scan_event__machine_already_exists( + handler: handle_ping_scan_event, + machine_repository: IMachineRepository, +): + machine_repository.get_machine_by_id = MagicMock(side_effect=lambda _: []) + handler(EVENT) + + expected_machine = TARGET_MACHINE.copy() + expected_machine.operating_system = OperatingSystem.LINUX + + machine_repository.upsert_machine.assert_called_with(expected_machine) + + +def test_handle_ping_scan_event__upserts_node( handler: handle_ping_scan_event, machine_repository: IMachineRepository, node_repository: INodeRepository, ): - machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + machine_repository.get_machine_by_id = MagicMock(return_value=TARGET_MACHINE) handler(EVENT) - assert node_repository.upsert_communication.called_with( - MACHINE.id, STORED_MACHINE.id, CommunicationType.SCANNED + node_repository.upsert_communication.assert_called_with( + PINGER_MACHINE.id, TARGET_MACHINE.id, CommunicationType.SCANNED ) -def test_handle_scan_data__node_not_upserted_if_no_matching_agent( +def test_handle_ping_scan_event__node_not_upserted_if_no_matching_agent( handler: handle_ping_scan_event, agent_repository: IAgentRepository, machine_repository: IMachineRepository, node_repository: INodeRepository, ): agent_repository.get_agent_by_id = MagicMock(side_effect=UnknownRecordError) - machine_repository.get_machine_by_id = MagicMock(return_value=STORED_MACHINE) + machine_repository.get_machine_by_id = MagicMock(return_value=TARGET_MACHINE) handler(EVENT) assert not node_repository.upsert_communication.called -def test_handle_scan_data__node_not_upserted_if_no_matching_machine( +def test_handle_ping_scan_event__node_not_upserted_if_no_matching_machine( handler: handle_ping_scan_event, machine_repository: IMachineRepository, node_repository: INodeRepository, @@ -128,7 +139,7 @@ def test_handle_scan_data__node_not_upserted_if_no_matching_machine( assert not node_repository.upsert_communication.called -def test_handle_scan_data__upserts_machine_if_not_existed( +def test_handle_ping_scan_event__upserts_machine_if_not_existed( handler: handle_ping_scan_event, machine_repository: IMachineRepository ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) @@ -136,4 +147,4 @@ def test_handle_scan_data__upserts_machine_if_not_existed( expected_machine = Machine(id=SEED_ID, operating_system=OperatingSystem.LINUX) - assert machine_repository.upsert_machine.called_with(expected_machine) + machine_repository.upsert_machine.assert_called_with(expected_machine) From 65d43575d17603681f9861539d6cc580d908c7eb Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Wed, 28 Sep 2022 16:04:49 +0000 Subject: [PATCH 16/30] UT: Make tests pass --- .../handle_ping_scan_event.py | 10 +-- .../test_handle_ping_scan_event.py | 84 ++++++++++++++++++- 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index 52fc34ddc..bae20b607 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -39,13 +39,13 @@ class handle_ping_scan_event: logger.exception("Unable to process ping scan data") def _get_destination_machine(self, event: PingScanEvent) -> Machine: - dest_machines = self._machine_repository.get_machines_by_ip(event.target) - if not dest_machines: + try: + dest_machines = self._machine_repository.get_machines_by_ip(event.target) + return dest_machines[0] + except UnknownRecordError: machine = Machine(id=self._machine_repository.get_new_id()) - dest_machines = [machine] self._machine_repository.upsert_machine(machine) - - return dest_machines[0] + return machine def _get_source_machine(self, event: PingScanEvent) -> Machine: agent = self._agent_repository.get_agent_by_id(event.source) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index 171266ae3..ba1a7ff60 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -14,6 +14,8 @@ from monkey_island.cc.repository import ( IAgentRepository, IMachineRepository, INodeRepository, + RetrievalError, + StorageError, UnknownRecordError, ) @@ -68,10 +70,51 @@ def handler(agent_repository, machine_repository, node_repository) -> handle_pin machines = {MACHINE_ID: PINGER_MACHINE, TARGET_MACHINE.id: TARGET_MACHINE} +machines_by_id = {MACHINE_ID: PINGER_MACHINE, TARGET_MACHINE.id: TARGET_MACHINE} +machines_by_ip = { + IPv4Address("10.10.10.99"): [PINGER_MACHINE], + IPv4Address("10.10.10.1"): [TARGET_MACHINE], +} def machine_from_id(id: int): - return machines[id] + return machines_by_id[id] + + +def machines_from_ip(ip: IPv4Address): + return machines_by_ip[ip] + + +class error_machine_by_id: + """Raise an error if the machine with the called ID matches the stored ID""" + + def __init__(self, id: int, error): + self.id = id + self.error = error + + def __call__(self, id: int): + if id == self.id: + raise self.error + else: + return machine_from_id(id) + + +class error_machine_by_ip: + """Raise an error if the machine with the called IP matches the stored ID""" + + def __init__(self, id: int, error): + self.id = id + self.error = error + + def __call__(self, ip: IPv4Address): + print(f"IP is: {ip}") + machines = machines_from_ip(ip) + if machines[0].id == self.id: + print(f"Raise error: {self.error}") + raise self.error + else: + print(f"Return machine: {machines}") + return machines def test_handle_ping_scan_event__upserts_machine( @@ -79,6 +122,7 @@ def test_handle_ping_scan_event__upserts_machine( machine_repository: IMachineRepository, ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) handler(EVENT) expected_machine = TARGET_MACHINE.copy() @@ -91,7 +135,8 @@ def test_handle_ping_scan_event__machine_already_exists( handler: handle_ping_scan_event, machine_repository: IMachineRepository, ): - machine_repository.get_machine_by_id = MagicMock(side_effect=lambda _: []) + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) handler(EVENT) expected_machine = TARGET_MACHINE.copy() @@ -105,7 +150,8 @@ def test_handle_ping_scan_event__upserts_node( machine_repository: IMachineRepository, node_repository: INodeRepository, ): - machine_repository.get_machine_by_id = MagicMock(return_value=TARGET_MACHINE) + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(return_value=[TARGET_MACHINE]) handler(EVENT) node_repository.upsert_communication.assert_called_with( @@ -143,8 +189,40 @@ def test_handle_ping_scan_event__upserts_machine_if_not_existed( handler: handle_ping_scan_event, machine_repository: IMachineRepository ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(side_effect=UnknownRecordError) handler(EVENT) expected_machine = Machine(id=SEED_ID, operating_system=OperatingSystem.LINUX) machine_repository.upsert_machine.assert_called_with(expected_machine) + + +@pytest.mark.parametrize("id", [PINGER_MACHINE.id, TARGET_MACHINE.id]) +def test_handle_scan_data__node_not_upserted_if_machine_retrievalerror( + handler: handle_ping_scan_event, + machine_repository: IMachineRepository, + node_repository: INodeRepository, + id, +): + machine_repository.get_machine_by_id = MagicMock( + side_effect=error_machine_by_id(id, RetrievalError) + ) + machine_repository.get_machines_by_ip = MagicMock( + side_effect=error_machine_by_ip(id, RetrievalError) + ) + + handler(EVENT) + + assert not node_repository.upsert_communication.called + + +def test_handle_scan_data__node_not_upserted_if_machine_storageerror( + handler: handle_ping_scan_event, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + machine_repository.upsert_machine = MagicMock(side_effect=StorageError) + + handler(EVENT) + + assert not node_repository.upsert_communication.called From 6aa69a10b6b4bbcff2eb65e2e8544afebbe2754b Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 29 Sep 2022 11:58:02 +0300 Subject: [PATCH 17/30] Island: Setup ping scan event listener/handler --- monkey/monkey_island/cc/setup/agent_event_handlers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/monkey_island/cc/setup/agent_event_handlers.py b/monkey/monkey_island/cc/setup/agent_event_handlers.py index 44861d766..9d6231b37 100644 --- a/monkey/monkey_island/cc/setup/agent_event_handlers.py +++ b/monkey/monkey_island/cc/setup/agent_event_handlers.py @@ -17,6 +17,7 @@ from monkey_island.cc.repository import ( def setup_agent_event_handlers(container: DIContainer): _subscribe_and_store_to_event_repository(container) + _subscribe_ping_scan_event(container) def _subscribe_and_store_to_event_repository(container: DIContainer): From 3d80adbcd510cfc54ca47e71102a7ffb529b5577 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 29 Sep 2022 13:00:53 +0300 Subject: [PATCH 18/30] Common: Flatten the ping scan event --- monkey/common/agent_events/ping_scan_event.py | 5 ++--- .../agent_event_handlers/handle_ping_scan_event.py | 4 ++-- .../test_handle_ping_scan_event.py | 12 ++++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/monkey/common/agent_events/ping_scan_event.py b/monkey/common/agent_events/ping_scan_event.py index 0e9ee6614..801876c95 100644 --- a/monkey/common/agent_events/ping_scan_event.py +++ b/monkey/common/agent_events/ping_scan_event.py @@ -2,7 +2,6 @@ from ipaddress import IPv4Address from typing import Optional from common import OperatingSystem - from . import AbstractAgentEvent @@ -11,8 +10,8 @@ class PingScanEvent(AbstractAgentEvent): An event that occurs when the agent performs a ping scan on its network Attributes: - :param response_received: Is any response from ping recieved - :param os: Operating system from the target system + :param response_received: Indicates if target responded to the ping + :param os: Operating system type determined by ICMP fingerprinting """ target: IPv4Address diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index bae20b607..fe7a2f150 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -52,6 +52,6 @@ class handle_ping_scan_event: return self._machine_repository.get_machine_by_id(agent.machine_id) def _update_destination_machine(self, machine: Machine, event: PingScanEvent): - if event.scan_data.os is not None: - machine.operating_system = event.scan_data.os + if event.os is not None: + machine.operating_system = event.os self._machine_repository.upsert_machine(machine) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index ba1a7ff60..d8c11f91e 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -7,7 +7,7 @@ import pytest from common import OperatingSystem from common.agent_events import PingScanEvent -from common.types import PingScanData, SocketAddress +from common.types import SocketAddress from monkey_island.cc.agent_event_handlers import handle_ping_scan_event from monkey_island.cc.models import Agent, CommunicationType, Machine from monkey_island.cc.repository import ( @@ -37,7 +37,15 @@ TARGET_MACHINE = Machine( EVENT = PingScanEvent( source=AGENT_ID, target=IPv4Address("10.10.10.1"), - scan_data=PingScanData(True, OperatingSystem.LINUX), + response_received=True, + os=OperatingSystem.LINUX, +) + +EVENT_NO_RESPONSE = PingScanEvent( + source=AGENT_ID, + target=IPv4Address("10.10.10.1"), + response_received=False, + os=OperatingSystem.LINUX, ) From 4d2a6083a157f4c7cd2611d539d8a6f1c274bd54 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 29 Sep 2022 13:02:04 +0300 Subject: [PATCH 19/30] Island: Fix a bug where failed ping scan created machines --- .../handle_ping_scan_event.py | 3 +++ .../test_handle_ping_scan_event.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index fe7a2f150..939261524 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -26,6 +26,9 @@ class handle_ping_scan_event: self._node_repository = node_repository def __call__(self, event: PingScanEvent): + if not event.response_received: + return + try: dest_machine = self._get_destination_machine(event) self._update_destination_machine(dest_machine, event) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index d8c11f91e..7d1d0889d 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -234,3 +234,18 @@ def test_handle_scan_data__node_not_upserted_if_machine_storageerror( handler(EVENT) assert not node_repository.upsert_communication.called + + +def test_handle_scan_data__failed_ping( + handler: handle_ping_scan_event, + machine_repository: IMachineRepository, + node_repository: INodeRepository, +): + machine_repository.upsert_machine = MagicMock(side_effect=StorageError) + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) + + handler(EVENT_NO_RESPONSE) + + assert not node_repository.upsert_communication.called + assert not machine_repository.upsert_machine.called From ff2b04c703d60e90fe5afab43e652b8086dec8b2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 29 Sep 2022 13:49:44 +0300 Subject: [PATCH 20/30] Common: Override target for PingScanEvent to more specific type hint --- monkey/common/agent_events/ping_scan_event.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/common/agent_events/ping_scan_event.py b/monkey/common/agent_events/ping_scan_event.py index 801876c95..22c910671 100644 --- a/monkey/common/agent_events/ping_scan_event.py +++ b/monkey/common/agent_events/ping_scan_event.py @@ -10,6 +10,7 @@ class PingScanEvent(AbstractAgentEvent): An event that occurs when the agent performs a ping scan on its network Attributes: + :param target: IP address of the pinged system :param response_received: Indicates if target responded to the ping :param os: Operating system type determined by ICMP fingerprinting """ From 9b307707777349e0d41c727f3683985ec7b2b581 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 29 Sep 2022 17:50:25 +0300 Subject: [PATCH 21/30] Island: Fix ping scan handler to add machines IP --- .../agent_event_handlers/handle_ping_scan_event.py | 12 +++++++++++- .../test_handle_ping_scan_event.py | 14 +------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index 939261524..9ea022e4a 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -1,5 +1,7 @@ from logging import getLogger +from pydantic.json import IPv4Interface + from common.agent_events import PingScanEvent from monkey_island.cc.models import CommunicationType, Machine from monkey_island.cc.repository import ( @@ -15,6 +17,11 @@ logger = getLogger(__name__) class handle_ping_scan_event: + """ + Handles ping scan event and makes changes to Machine and Node states based on it + :param event: Ping scan event + """ + def __init__( self, agent_repository: IAgentRepository, @@ -46,7 +53,10 @@ class handle_ping_scan_event: dest_machines = self._machine_repository.get_machines_by_ip(event.target) return dest_machines[0] except UnknownRecordError: - machine = Machine(id=self._machine_repository.get_new_id()) + machine = Machine( + id=self._machine_repository.get_new_id(), + network_interfaces=[IPv4Interface(event.target)], + ) self._machine_repository.upsert_machine(machine) return machine diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index 7d1d0889d..e461b584c 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -130,7 +130,7 @@ def test_handle_ping_scan_event__upserts_machine( machine_repository: IMachineRepository, ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) - machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) + machine_repository.get_machines_by_ip = MagicMock(side_effect=UnknownRecordError) handler(EVENT) expected_machine = TARGET_MACHINE.copy() @@ -193,18 +193,6 @@ def test_handle_ping_scan_event__node_not_upserted_if_no_matching_machine( assert not node_repository.upsert_communication.called -def test_handle_ping_scan_event__upserts_machine_if_not_existed( - handler: handle_ping_scan_event, machine_repository: IMachineRepository -): - machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) - machine_repository.get_machines_by_ip = MagicMock(side_effect=UnknownRecordError) - handler(EVENT) - - expected_machine = Machine(id=SEED_ID, operating_system=OperatingSystem.LINUX) - - machine_repository.upsert_machine.assert_called_with(expected_machine) - - @pytest.mark.parametrize("id", [PINGER_MACHINE.id, TARGET_MACHINE.id]) def test_handle_scan_data__node_not_upserted_if_machine_retrievalerror( handler: handle_ping_scan_event, From d811c6548cef36f8e92db5229bb8c7a776a71c17 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 11:30:31 -0400 Subject: [PATCH 22/30] Island: Prefer existing OS data to ping OS data Co-authored-by: Mike Salvatore --- .../cc/agent_event_handlers/handle_ping_scan_event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index 9ea022e4a..f0a98757b 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -65,6 +65,6 @@ class handle_ping_scan_event: return self._machine_repository.get_machine_by_id(agent.machine_id) def _update_destination_machine(self, machine: Machine, event: PingScanEvent): - if event.os is not None: + if event.os is not None and machine.operating_system is None: machine.operating_system = event.os self._machine_repository.upsert_machine(machine) From 9a880123da49dbd3044bdea220c98424366a9bef Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 16:26:27 +0000 Subject: [PATCH 23/30] UT: Fix failing tests --- .../agent_event_handlers/test_handle_ping_scan_event.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index e461b584c..1e2e18789 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -125,7 +125,7 @@ class error_machine_by_ip: return machines -def test_handle_ping_scan_event__upserts_machine( +def test_handle_ping_scan_event__target_machine_not_exists( handler: handle_ping_scan_event, machine_repository: IMachineRepository, ): @@ -133,13 +133,13 @@ def test_handle_ping_scan_event__upserts_machine( machine_repository.get_machines_by_ip = MagicMock(side_effect=UnknownRecordError) handler(EVENT) - expected_machine = TARGET_MACHINE.copy() - expected_machine.operating_system = OperatingSystem.LINUX + expected_machine = Machine(id=SEED_ID, network_interfaces=[IPv4Interface(EVENT.target)]) + expected_machine.operating_system = EVENT.os machine_repository.upsert_machine.assert_called_with(expected_machine) -def test_handle_ping_scan_event__machine_already_exists( +def test_handle_ping_scan_event__target_machine_already_exists( handler: handle_ping_scan_event, machine_repository: IMachineRepository, ): From 783cc06c0d9b3dd23aabedfc6bab8d883bda0ec2 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 16:58:24 +0000 Subject: [PATCH 24/30] Common: Mitigate mypy errors from DIContainer --- monkey/common/di_container.py | 9 ++++++++- monkey/monkey_island/cc/setup/agent_event_handlers.py | 10 ++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/monkey/common/di_container.py b/monkey/common/di_container.py index 06df8e591..eb5361769 100644 --- a/monkey/common/di_container.py +++ b/monkey/common/di_container.py @@ -1,6 +1,6 @@ import inspect from contextlib import suppress -from typing import Any, Sequence, Type, TypeVar +from typing import Any, Sequence, Type, TypeVar, no_type_check from common.utils.code_utils import del_key @@ -15,6 +15,9 @@ class UnregisteredConventionError(ValueError): pass +# Mypy doesn't handle cases where abstract class is passed as Type[...] +# https://github.com/python/mypy/issues/4717 +# We are using typing.no_type_check to mitigate these errors class DIContainer: """ A dependency injection (DI) container that uses type annotations to resolve and inject @@ -26,6 +29,7 @@ class DIContainer: self._instance_registry = {} self._convention_registry = {} + @no_type_check def register(self, interface: Type[T], concrete_type: Type[T]): """ Register a concrete `type` that satisfies a given interface. @@ -55,6 +59,7 @@ class DIContainer: self._type_registry[interface] = concrete_type del_key(self._instance_registry, interface) + @no_type_check def register_instance(self, interface: Type[T], instance: T): """ Register a concrete instance that satisfies a given interface. @@ -73,6 +78,7 @@ class DIContainer: self._instance_registry[interface] = instance del_key(self._type_registry, interface) + @no_type_check def register_convention(self, type_: Type[T], name: str, instance: T): """ Register an instance as a convention @@ -101,6 +107,7 @@ class DIContainer: """ self._convention_registry[(type_, name)] = instance + @no_type_check def resolve(self, type_: Type[T]) -> T: """ Resolves all dependencies and returns a new instance of `type_` using constructor dependency diff --git a/monkey/monkey_island/cc/setup/agent_event_handlers.py b/monkey/monkey_island/cc/setup/agent_event_handlers.py index 9d6231b37..2cc1bf3da 100644 --- a/monkey/monkey_island/cc/setup/agent_event_handlers.py +++ b/monkey/monkey_island/cc/setup/agent_event_handlers.py @@ -33,12 +33,10 @@ def _subscribe_and_store_to_event_repository(container: DIContainer): def _subscribe_ping_scan_event(container: DIContainer): - # Mypy don't handle cases where abstract class is passed as Type[...] - # https://github.com/python/mypy/issues/4717 - agent_event_queue = container.resolve(IAgentEventQueue) # type: ignore - agent_repository = container.resolve(IAgentRepository) # type: ignore - machine_repository = container.resolve(IMachineRepository) # type: ignore - node_repository = container.resolve(INodeRepository) # type: ignore + agent_event_queue = container.resolve(IAgentEventQueue) + agent_repository = container.resolve(IAgentRepository) + machine_repository = container.resolve(IMachineRepository) + node_repository = container.resolve(INodeRepository) handler = handle_ping_scan_event(agent_repository, machine_repository, node_repository) From c06d06edc4330773207ccb1960c3515bf4705f32 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 18:05:58 +0000 Subject: [PATCH 25/30] UT: Fix storageerror test --- .../test_handle_ping_scan_event.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index 1e2e18789..cd29591a7 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -212,11 +212,39 @@ def test_handle_scan_data__node_not_upserted_if_machine_retrievalerror( assert not node_repository.upsert_communication.called +def test_handle_scan_data__machine_not_upserted_if_os_is_none( + handler: handle_ping_scan_event, machine_repository: IMachineRepository +): + event = PingScanEvent(source=EVENT.source, target=EVENT.target, response_received=True, os=None) + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) + + handler(event) + + assert not machine_repository.upsert_machine.called + + +def test_handle_scan_data__machine_not_upserted_if_existing_machine_has_os( + handler: handle_ping_scan_event, machine_repository: IMachineRepository +): + machine_with_os = TARGET_MACHINE + machine_with_os.operating_system = OperatingSystem.WINDOWS + machine_repository.get_machine_by_ip = MagicMock(return_value=machine_with_os) + + handler(EVENT) + + assert not machine_repository.upsert_machine.called + + def test_handle_scan_data__node_not_upserted_if_machine_storageerror( handler: handle_ping_scan_event, machine_repository: IMachineRepository, node_repository: INodeRepository, ): + target_machine = TARGET_MACHINE + target_machine.operating_system = None + machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) + machine_repository.get_machines_by_ip = MagicMock(return_value=target_machine) machine_repository.upsert_machine = MagicMock(side_effect=StorageError) handler(EVENT) From 2aa79331e3d2bda61b62861d10abd9f3c6db8a7c Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 29 Sep 2022 15:04:29 -0400 Subject: [PATCH 26/30] Island: Extract method to improve readablility --- .../handle_ping_scan_event.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index f0a98757b..f73f461e3 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -38,13 +38,9 @@ class handle_ping_scan_event: try: dest_machine = self._get_destination_machine(event) - self._update_destination_machine(dest_machine, event) - src_machine = self._get_source_machine(event) - # Update or create the node - self._node_repository.upsert_communication( - src_machine.id, dest_machine.id, CommunicationType.SCANNED - ) + self._update_destination_machine_os(dest_machine, event) + self._update_nodes(dest_machine, event) except (RetrievalError, StorageError, TypeError, UnknownRecordError): logger.exception("Unable to process ping scan data") @@ -60,11 +56,19 @@ class handle_ping_scan_event: self._machine_repository.upsert_machine(machine) return machine - def _get_source_machine(self, event: PingScanEvent) -> Machine: - agent = self._agent_repository.get_agent_by_id(event.source) - return self._machine_repository.get_machine_by_id(agent.machine_id) - - def _update_destination_machine(self, machine: Machine, event: PingScanEvent): + def _update_destination_machine_os(self, machine: Machine, event: PingScanEvent): if event.os is not None and machine.operating_system is None: machine.operating_system = event.os self._machine_repository.upsert_machine(machine) + + def _update_nodes(self, dest_machine, event): + src_machine = self._get_source_machine(event) + + # Update or create the node + self._node_repository.upsert_communication( + src_machine.id, dest_machine.id, CommunicationType.SCANNED + ) + + def _get_source_machine(self, event: PingScanEvent) -> Machine: + agent = self._agent_repository.get_agent_by_id(event.source) + return self._machine_repository.get_machine_by_id(agent.machine_id) From c632b9b77bb578bd7203ed71e87cfe3976278dc0 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 29 Sep 2022 15:09:29 -0400 Subject: [PATCH 27/30] Island: Rename dest -> target --- .../handle_ping_scan_event.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index f73f461e3..18e66c52a 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -37,17 +37,17 @@ class handle_ping_scan_event: return try: - dest_machine = self._get_destination_machine(event) + target_machine = self._get_target_machine(event) - self._update_destination_machine_os(dest_machine, event) - self._update_nodes(dest_machine, event) + self._update_target_machine_os(target_machine, event) + self._update_nodes(target_machine, event) except (RetrievalError, StorageError, TypeError, UnknownRecordError): logger.exception("Unable to process ping scan data") - def _get_destination_machine(self, event: PingScanEvent) -> Machine: + def _get_target_machine(self, event: PingScanEvent) -> Machine: try: - dest_machines = self._machine_repository.get_machines_by_ip(event.target) - return dest_machines[0] + target_machines = self._machine_repository.get_machines_by_ip(event.target) + return target_machines[0] except UnknownRecordError: machine = Machine( id=self._machine_repository.get_new_id(), @@ -56,17 +56,17 @@ class handle_ping_scan_event: self._machine_repository.upsert_machine(machine) return machine - def _update_destination_machine_os(self, machine: Machine, event: PingScanEvent): + def _update_target_machine_os(self, machine: Machine, event: PingScanEvent): if event.os is not None and machine.operating_system is None: machine.operating_system = event.os self._machine_repository.upsert_machine(machine) - def _update_nodes(self, dest_machine, event): + def _update_nodes(self, target_machine, event): src_machine = self._get_source_machine(event) # Update or create the node self._node_repository.upsert_communication( - src_machine.id, dest_machine.id, CommunicationType.SCANNED + src_machine.id, target_machine.id, CommunicationType.SCANNED ) def _get_source_machine(self, event: PingScanEvent) -> Machine: From c1dcb285ae889c4e9900d512f808dcf0887c3132 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 19:36:18 +0000 Subject: [PATCH 28/30] UT: Properly group arrange/assert/act steps --- .../cc/agent_event_handlers/test_handle_ping_scan_event.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py index cd29591a7..d0af268e1 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py +++ b/monkey/tests/unit_tests/monkey_island/cc/agent_event_handlers/test_handle_ping_scan_event.py @@ -131,11 +131,11 @@ def test_handle_ping_scan_event__target_machine_not_exists( ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) machine_repository.get_machines_by_ip = MagicMock(side_effect=UnknownRecordError) + handler(EVENT) expected_machine = Machine(id=SEED_ID, network_interfaces=[IPv4Interface(EVENT.target)]) expected_machine.operating_system = EVENT.os - machine_repository.upsert_machine.assert_called_with(expected_machine) @@ -145,11 +145,11 @@ def test_handle_ping_scan_event__target_machine_already_exists( ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) machine_repository.get_machines_by_ip = MagicMock(side_effect=machines_from_ip) + handler(EVENT) expected_machine = TARGET_MACHINE.copy() expected_machine.operating_system = OperatingSystem.LINUX - machine_repository.upsert_machine.assert_called_with(expected_machine) @@ -160,6 +160,7 @@ def test_handle_ping_scan_event__upserts_node( ): machine_repository.get_machine_by_id = MagicMock(side_effect=machine_from_id) machine_repository.get_machines_by_ip = MagicMock(return_value=[TARGET_MACHINE]) + handler(EVENT) node_repository.upsert_communication.assert_called_with( From a267f02ca9b5fec275e5716af0f2c986f4ba9e18 Mon Sep 17 00:00:00 2001 From: Kekoa Kaaikala Date: Thu, 29 Sep 2022 19:43:14 +0000 Subject: [PATCH 29/30] Island: Move param docstring to __call__ method --- .../cc/agent_event_handlers/handle_ping_scan_event.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py index 18e66c52a..5eb477723 100644 --- a/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py +++ b/monkey/monkey_island/cc/agent_event_handlers/handle_ping_scan_event.py @@ -19,7 +19,6 @@ logger = getLogger(__name__) class handle_ping_scan_event: """ Handles ping scan event and makes changes to Machine and Node states based on it - :param event: Ping scan event """ def __init__( @@ -33,6 +32,9 @@ class handle_ping_scan_event: self._node_repository = node_repository def __call__(self, event: PingScanEvent): + """ + :param event: Ping scan event to process + """ if not event.response_received: return From 7ed071b56536e45433e2d605769936efd6b02828 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 30 Sep 2022 09:47:20 +0300 Subject: [PATCH 30/30] Common: Fix imports in ping_scan_event.py --- monkey/common/agent_events/ping_scan_event.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/common/agent_events/ping_scan_event.py b/monkey/common/agent_events/ping_scan_event.py index 22c910671..e9aef14ed 100644 --- a/monkey/common/agent_events/ping_scan_event.py +++ b/monkey/common/agent_events/ping_scan_event.py @@ -2,6 +2,7 @@ from ipaddress import IPv4Address from typing import Optional from common import OperatingSystem + from . import AbstractAgentEvent