diff --git a/monkey/infection_monkey/master/exploiter.py b/monkey/infection_monkey/master/exploiter.py index 5a76b20a8..151280ea0 100644 --- a/monkey/infection_monkey/master/exploiter.py +++ b/monkey/infection_monkey/master/exploiter.py @@ -110,12 +110,23 @@ class Exploiter: def _run_exploiter( self, exploiter_name: str, options: Dict, victim_host: VictimHost, stop: Event ) -> ExploiterResultData: - logger.debug(f"Attempting to use {exploiter_name} on {victim_host}") + logger.debug(f"Attempting to use {exploiter_name} on {victim_host.ip_addr}") credentials = self._get_credentials_for_propagation() options = {"credentials": credentials, **options} - return self._puppet.exploit_host(exploiter_name, victim_host, options, stop) + try: + return self._puppet.exploit_host(exploiter_name, victim_host, options, stop) + except Exception as ex: + msg = ( + f"An unexpected error occurred while exploiting {victim_host.ip_addr} with " + f"{exploiter_name}: {ex}" + ) + logger.error(msg) + + return ExploiterResultData( + exploitation_success=False, propagation_success=False, error_message=msg + ) def _get_credentials_for_propagation(self) -> Mapping: try: diff --git a/monkey/tests/unit_tests/infection_monkey/master/test_exploiter.py b/monkey/tests/unit_tests/infection_monkey/master/test_exploiter.py index 9a276e9aa..c32ad5acb 100644 --- a/monkey/tests/unit_tests/infection_monkey/master/test_exploiter.py +++ b/monkey/tests/unit_tests/infection_monkey/master/test_exploiter.py @@ -124,3 +124,18 @@ def test_stop_after_callback(exploiter_config, callback, scan_completed, stop, h e.exploit_hosts(exploiter_config, hosts_to_exploit, stoppable_callback, scan_completed, stop) assert stoppable_callback.call_count == 2 + + +def test_exploiter_raises_exception(callback, hosts, hosts_to_exploit, run_exploiters): + error_message = "Unexpected error" + mock_puppet = MockPuppet() + mock_puppet.exploit_host = MagicMock(side_effect=Exception(error_message)) + run_exploiters(mock_puppet, 3) + + assert callback.call_count == 6 + + for i in range(0, 6): + exploit_result_data = callback.call_args_list[i][0][2] + assert exploit_result_data.exploitation_success is False + assert exploit_result_data.propagation_success is False + assert error_message in exploit_result_data.error_message