Agent: Use deserialized in exploiter.py and propagator.py

This commit is contained in:
vakarisz 2022-06-22 17:52:34 +03:00 committed by Mike Salvatore
parent 095e49b543
commit 9286e86900
3 changed files with 55 additions and 30 deletions

View File

@ -5,9 +5,13 @@ from copy import deepcopy
from itertools import chain from itertools import chain
from queue import Queue from queue import Queue
from threading import Event from threading import Event
from typing import Callable, Dict, List, Mapping from typing import Callable, Dict, List
from common import OperatingSystems from common import OperatingSystems
from common.configuration.agent_sub_configurations import (
ExploitationConfiguration,
ExploiterConfiguration,
)
from infection_monkey.custom_types import PropagationCredentials from infection_monkey.custom_types import PropagationCredentials
from infection_monkey.i_puppet import ExploiterResultData, IPuppet from infection_monkey.i_puppet import ExploiterResultData, IPuppet
from infection_monkey.model import VictimHost from infection_monkey.model import VictimHost
@ -46,7 +50,7 @@ class Exploiter:
def exploit_hosts( def exploit_hosts(
self, self,
exploiter_config: Dict, exploiter_config: ExploitationConfiguration,
hosts_to_exploit: Queue, hosts_to_exploit: Queue,
current_depth: int, current_depth: int,
results_callback: Callback, results_callback: Callback,
@ -56,7 +60,7 @@ class Exploiter:
exploiters_to_run = self._process_exploiter_config(exploiter_config) exploiters_to_run = self._process_exploiter_config(exploiter_config)
logger.debug( logger.debug(
"Agent is configured to run the following exploiters in order: " "Agent is configured to run the following exploiters in order: "
f"{', '.join([e['name'] for e in exploiters_to_run])}" f"{', '.join([e.name for e in exploiters_to_run])}"
) )
exploit_args = ( exploit_args = (
@ -75,24 +79,28 @@ class Exploiter:
) )
@staticmethod @staticmethod
def _process_exploiter_config(exploiter_config: Mapping) -> List[Mapping]: def _process_exploiter_config(
exploiter_config: ExploitationConfiguration,
) -> List[ExploiterConfiguration]:
# Run vulnerability exploiters before brute force exploiters to minimize the effect of # Run vulnerability exploiters before brute force exploiters to minimize the effect of
# account lockout due to invalid credentials # account lockout due to invalid credentials
ordered_exploiters = chain( ordered_exploiters = chain(exploiter_config.vulnerability, exploiter_config.brute_force)
exploiter_config["vulnerability"], exploiter_config["brute_force"]
)
exploiters_to_run = list(deepcopy(ordered_exploiters)) exploiters_to_run = list(deepcopy(ordered_exploiters))
extended_exploiters = []
for exploiter in exploiters_to_run: for exploiter in exploiters_to_run:
# This order allows exploiter-specific options to # This order allows exploiter-specific options to
# override general options for all exploiters. # override general options for all exploiters.
exploiter["options"] = {**exploiter_config["options"], **exploiter["options"]} options = {**exploiter_config.options.__dict__, **exploiter.options}
extended_exploiters.append(
ExploiterConfiguration(exploiter.name, options, exploiter.supported_os)
)
return exploiters_to_run return extended_exploiters
def _exploit_hosts_on_queue( def _exploit_hosts_on_queue(
self, self,
exploiters_to_run: List[Dict], exploiters_to_run: List[ExploiterConfiguration],
hosts_to_exploit: Queue, hosts_to_exploit: Queue,
current_depth: int, current_depth: int,
results_callback: Callback, results_callback: Callback,
@ -119,7 +127,7 @@ class Exploiter:
def _run_all_exploiters( def _run_all_exploiters(
self, self,
exploiters_to_run: List[Dict], exploiters_to_run: List[ExploiterConfiguration],
victim_host: VictimHost, victim_host: VictimHost,
current_depth: int, current_depth: int,
results_callback: Callback, results_callback: Callback,
@ -127,7 +135,7 @@ class Exploiter:
): ):
for exploiter in interruptible_iter(exploiters_to_run, stop): for exploiter in interruptible_iter(exploiters_to_run, stop):
exploiter_name = exploiter["name"] exploiter_name = exploiter.name
victim_os = victim_host.os.get("type") victim_os = victim_host.os.get("type")
# We want to try all exploiters if the victim's OS is unknown # We want to try all exploiters if the victim's OS is unknown
@ -140,7 +148,7 @@ class Exploiter:
continue continue
exploiter_results = self._run_exploiter( exploiter_results = self._run_exploiter(
exploiter_name, exploiter["options"], victim_host, current_depth, stop exploiter_name, exploiter.options, victim_host, current_depth, stop
) )
results_callback(exploiter_name, victim_host, exploiter_results) results_callback(exploiter_name, victim_host, exploiter_results)

View File

@ -1,10 +1,13 @@
import logging import logging
from queue import Queue from queue import Queue
from threading import Event from threading import Event
from typing import Dict, List from typing import List
from common.configuration import PropagationConfiguration,\ from common.configuration import (
NetworkScanConfiguration, ScanTargetConfiguration NetworkScanConfiguration,
PropagationConfiguration,
ScanTargetConfiguration,
)
from infection_monkey.i_puppet import ( from infection_monkey.i_puppet import (
ExploiterResultData, ExploiterResultData,
FingerprintData, FingerprintData,
@ -139,14 +142,14 @@ class Propagator:
def _exploit_hosts( def _exploit_hosts(
self, self,
propagation_config: Dict, propagation_config: PropagationConfiguration,
current_depth: int, current_depth: int,
network_scan_completed: Event, network_scan_completed: Event,
stop: Event, stop: Event,
): ):
logger.info("Exploiting victims") logger.info("Exploiting victims")
exploiter_config = propagation_config["exploiters"] exploiter_config = propagation_config.exploitation
self._exploiter.exploit_hosts( self._exploiter.exploit_hosts(
exploiter_config, exploiter_config,
self._hosts_to_exploit, self._hosts_to_exploit,

View File

@ -8,6 +8,10 @@ import pytest
from tests.unit_tests.infection_monkey.master.mock_puppet import MockPuppet from tests.unit_tests.infection_monkey.master.mock_puppet import MockPuppet
from common import OperatingSystems from common import OperatingSystems
from common.configuration.agent_sub_configurations import (
ExploitationConfiguration,
ExploiterConfiguration,
)
from infection_monkey.master import Exploiter from infection_monkey.master import Exploiter
from infection_monkey.model import VictimHost from infection_monkey.model import VictimHost
@ -35,18 +39,28 @@ def callback():
@pytest.fixture @pytest.fixture
def exploiter_config(): def exploiter_config(default_agent_config):
return { brute_force = [
"options": {"dropper_path_linux": "/tmp/monkey"}, ExploiterConfiguration(
"brute_force": [ name="MSSQLExploiter", options={"timeout": 10}
{"name": "MSSQLExploiter", "options": {"timeout": 10}}, ),
{"name": "SSHExploiter", "options": {}}, ExploiterConfiguration(
{"name": "WmiExploiter", "options": {"timeout": 10}}, name="SSHExploiter", options={}
], ),
"vulnerability": [ ExploiterConfiguration(
{"name": "ZerologonExploiter", "options": {}}, name="WmiExploiter", options={"timeout": 10}
], ),
} ]
vulnerability = [
ExploiterConfiguration(
name="ZerologonExploiter", options={}
)
]
return ExploitationConfiguration(
options=default_agent_config.propagation.exploitation.options,
brute_force=brute_force,
vulnerability=vulnerability,
)
@pytest.fixture @pytest.fixture