Merge pull request #2178 from guardicore/2169-icredentialstore-renaming

2169 ICredentialStore renaming
This commit is contained in:
Mike Salvatore 2022-08-08 11:27:29 -04:00 committed by GitHub
commit b2fa790db8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 49 additions and 35 deletions

View File

@ -0,0 +1,4 @@
from .i_propagation_credentials_repository import IPropagationCredentialsRepository
from .aggregating_propagation_credentials_repository import (
AggregatingPropagationCredentialsRepository,
)

View File

@ -6,14 +6,19 @@ from infection_monkey.custom_types import PropagationCredentials
from infection_monkey.i_control_channel import IControlChannel from infection_monkey.i_control_channel import IControlChannel
from infection_monkey.utils.decorators import request_cache from infection_monkey.utils.decorators import request_cache
from .i_credentials_store import ICredentialsStore from .i_propagation_credentials_repository import IPropagationCredentialsRepository
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
CREDENTIALS_POLL_PERIOD_SEC = 10 CREDENTIALS_POLL_PERIOD_SEC = 10
class AggregatingCredentialsStore(ICredentialsStore): class AggregatingPropagationCredentialsRepository(IPropagationCredentialsRepository):
"""
Repository that stores credentials on the island and saves/gets credentials by using
command and control channel
"""
def __init__(self, control_channel: IControlChannel): def __init__(self, control_channel: IControlChannel):
self._stored_credentials = { self._stored_credentials = {
"exploit_user_list": set(), "exploit_user_list": set(),

View File

@ -5,12 +5,16 @@ from common.credentials import Credentials
from infection_monkey.custom_types import PropagationCredentials from infection_monkey.custom_types import PropagationCredentials
class ICredentialsStore(metaclass=abc.ABCMeta): class IPropagationCredentialsRepository(metaclass=abc.ABCMeta):
"""
Repository that stores and provides credentials for the Agent to use in propagation
"""
@abc.abstractmethod @abc.abstractmethod
def add_credentials(self, credentials_to_add: Iterable[Credentials]): def add_credentials(self, credentials_to_add: Iterable[Credentials]):
""" """
Adds credentials to the CredentialStore Adds credentials to the CredentialStore
:param Iterable[Credentials] credentials: The credentials that will be added :param credentials_to_add: The credentials that will be added
""" """
@abc.abstractmethod @abc.abstractmethod
@ -18,5 +22,4 @@ class ICredentialsStore(metaclass=abc.ABCMeta):
""" """
Retrieves credentials from the store Retrieves credentials from the store
:return: Credentials that can be used for propagation :return: Credentials that can be used for propagation
:type: PropagationCredentials
""" """

View File

@ -1,2 +0,0 @@
from .i_credentials_store import ICredentialsStore
from .aggregating_credentials_store import AggregatingCredentialsStore

View File

@ -5,7 +5,7 @@ from typing import Any, Callable, Iterable, List, Optional
from common.agent_configuration import CustomPBAConfiguration, PluginConfiguration from common.agent_configuration import CustomPBAConfiguration, PluginConfiguration
from common.utils import Timer from common.utils import Timer
from infection_monkey.credential_store import ICredentialsStore from infection_monkey.credential_repository import IPropagationCredentialsRepository
from infection_monkey.i_control_channel import IControlChannel, IslandCommunicationError from infection_monkey.i_control_channel import IControlChannel, IslandCommunicationError
from infection_monkey.i_master import IMaster from infection_monkey.i_master import IMaster
from infection_monkey.i_puppet import IPuppet from infection_monkey.i_puppet import IPuppet
@ -40,7 +40,7 @@ class AutomatedMaster(IMaster):
victim_host_factory: VictimHostFactory, victim_host_factory: VictimHostFactory,
control_channel: IControlChannel, control_channel: IControlChannel,
local_network_interfaces: List[NetworkInterface], local_network_interfaces: List[NetworkInterface],
credentials_store: ICredentialsStore, credentials_store: IPropagationCredentialsRepository,
): ):
self._current_depth = current_depth self._current_depth = current_depth
self._puppet = puppet self._puppet = puppet

View File

@ -17,7 +17,10 @@ from infection_monkey.credential_collectors import (
MimikatzCredentialCollector, MimikatzCredentialCollector,
SSHCredentialCollector, SSHCredentialCollector,
) )
from infection_monkey.credential_store import AggregatingCredentialsStore, ICredentialsStore from infection_monkey.credential_store import (
AggregatingPropagationCredentialsRepository,
IPropagationCredentialsRepository,
)
from infection_monkey.exploit import CachingAgentRepository, ExploiterWrapper from infection_monkey.exploit import CachingAgentRepository, ExploiterWrapper
from infection_monkey.exploit.hadoop import HadoopExploiter from infection_monkey.exploit.hadoop import HadoopExploiter
from infection_monkey.exploit.log4shell import Log4ShellExploiter from infection_monkey.exploit.log4shell import Log4ShellExploiter
@ -195,7 +198,7 @@ class InfectionMonkey:
control_channel = ControlChannel( control_channel = ControlChannel(
self._control_client.server_address, GUID, self._control_client.proxies self._control_client.server_address, GUID, self._control_client.proxies
) )
credentials_store = AggregatingCredentialsStore(control_channel) credentials_store = AggregatingPropagationCredentialsRepository(control_channel)
puppet = self._build_puppet(credentials_store) puppet = self._build_puppet(credentials_store)
@ -226,7 +229,7 @@ class InfectionMonkey:
return local_network_interfaces return local_network_interfaces
def _build_puppet(self, credentials_store: ICredentialsStore) -> IPuppet: def _build_puppet(self, credentials_store: IPropagationCredentialsRepository) -> IPuppet:
puppet = Puppet() puppet = Puppet()
puppet.load_plugin( puppet.load_plugin(

View File

@ -1,6 +1,6 @@
from functools import singledispatch from functools import singledispatch
from infection_monkey.credential_store import ICredentialsStore from infection_monkey.credential_repository import IPropagationCredentialsRepository
from infection_monkey.telemetry.credentials_telem import CredentialsTelem from infection_monkey.telemetry.credentials_telem import CredentialsTelem
from infection_monkey.telemetry.i_telem import ITelem from infection_monkey.telemetry.i_telem import ITelem
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
@ -8,7 +8,9 @@ from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemet
class CredentialsInterceptingTelemetryMessenger(ITelemetryMessenger): class CredentialsInterceptingTelemetryMessenger(ITelemetryMessenger):
def __init__( def __init__(
self, telemetry_messenger: ITelemetryMessenger, credentials_store: ICredentialsStore self,
telemetry_messenger: ITelemetryMessenger,
credentials_store: IPropagationCredentialsRepository,
): ):
self._telemetry_messenger = telemetry_messenger self._telemetry_messenger = telemetry_messenger
self._credentials_store = credentials_store self._credentials_store = credentials_store
@ -23,7 +25,7 @@ class CredentialsInterceptingTelemetryMessenger(ITelemetryMessenger):
def _send_telemetry( def _send_telemetry(
telemetry: ITelem, telemetry: ITelem,
telemetry_messenger: ITelemetryMessenger, telemetry_messenger: ITelemetryMessenger,
credentials_store: ICredentialsStore, credentials_store: IPropagationCredentialsRepository,
): ):
telemetry_messenger.send_telemetry(telemetry) telemetry_messenger.send_telemetry(telemetry)
@ -32,7 +34,7 @@ def _send_telemetry(
def _( def _(
telemetry: CredentialsTelem, telemetry: CredentialsTelem,
telemetry_messenger: ITelemetryMessenger, telemetry_messenger: ITelemetryMessenger,
credentials_store: ICredentialsStore, credentials_store: IPropagationCredentialsRepository,
): ):
credentials_store.add_credentials(telemetry.credentials) credentials_store.add_credentials(telemetry.credentials)
telemetry_messenger.send_telemetry(telemetry) telemetry_messenger.send_telemetry(telemetry)

View File

@ -1,11 +1,10 @@
from datetime import datetime from datetime import datetime
from enum import Enum from enum import Enum
from json import loads from json import JSONEncoder, dumps, loads
from typing import Any from typing import Any
import bson import bson
from flask import make_response from flask import make_response
from flask.json import JSONEncoder, dumps
from common.utils import IJSONSerializable from common.utils import IJSONSerializable

View File

@ -15,7 +15,7 @@ from tests.data_for_tests.propagation_credentials import (
) )
from common.credentials import Credentials, LMHash, NTHash, Password, SSHKeypair, Username from common.credentials import Credentials, LMHash, NTHash, Password, SSHKeypair, Username
from infection_monkey.credential_store import AggregatingCredentialsStore from infection_monkey.credential_repository import AggregatingPropagationCredentialsRepository
CONTROL_CHANNEL_CREDENTIALS = PROPAGATION_CREDENTIALS CONTROL_CHANNEL_CREDENTIALS = PROPAGATION_CREDENTIALS
TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS = { TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS = {
@ -67,24 +67,24 @@ STOLEN_SSH_KEYS_CREDENTIALS = [
@pytest.fixture @pytest.fixture
def aggregating_credentials_store() -> AggregatingCredentialsStore: def aggregating_credentials_repository() -> AggregatingPropagationCredentialsRepository:
control_channel = MagicMock() control_channel = MagicMock()
control_channel.get_credentials_for_propagation.return_value = CONTROL_CHANNEL_CREDENTIALS control_channel.get_credentials_for_propagation.return_value = CONTROL_CHANNEL_CREDENTIALS
return AggregatingCredentialsStore(control_channel) return AggregatingPropagationCredentialsRepository(control_channel)
@pytest.mark.parametrize("key", TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS.keys()) @pytest.mark.parametrize("key", TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS.keys())
def test_get_credentials_from_store(aggregating_credentials_store, key): def test_get_credentials_from_repository(aggregating_credentials_repository, key):
actual_stored_credentials = aggregating_credentials_store.get_credentials() actual_stored_credentials = aggregating_credentials_repository.get_credentials()
assert actual_stored_credentials[key] == TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS[key] assert actual_stored_credentials[key] == TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS[key]
def test_add_credentials_to_store(aggregating_credentials_store): def test_add_credentials_to_repository(aggregating_credentials_repository):
aggregating_credentials_store.add_credentials(STOLEN_CREDENTIALS) aggregating_credentials_repository.add_credentials(STOLEN_CREDENTIALS)
aggregating_credentials_store.add_credentials(STOLEN_SSH_KEYS_CREDENTIALS) aggregating_credentials_repository.add_credentials(STOLEN_SSH_KEYS_CREDENTIALS)
actual_stored_credentials = aggregating_credentials_store.get_credentials() actual_stored_credentials = aggregating_credentials_repository.get_credentials()
assert actual_stored_credentials["exploit_user_list"] == set( assert actual_stored_credentials["exploit_user_list"] == set(
[ [
@ -113,9 +113,9 @@ def test_add_credentials_to_store(aggregating_credentials_store):
def test_all_keys_if_credentials_empty(): def test_all_keys_if_credentials_empty():
control_channel = MagicMock() control_channel = MagicMock()
control_channel.get_credentials_for_propagation.return_value = EMPTY_CHANNEL_CREDENTIALS control_channel.get_credentials_for_propagation.return_value = EMPTY_CHANNEL_CREDENTIALS
credentials_store = AggregatingCredentialsStore(control_channel) credentials_repository = AggregatingPropagationCredentialsRepository(control_channel)
actual_stored_credentials = credentials_store.get_credentials() actual_stored_credentials = credentials_repository.get_credentials()
print(type(actual_stored_credentials)) print(type(actual_stored_credentials))
assert "exploit_user_list" in actual_stored_credentials assert "exploit_user_list" in actual_stored_credentials

View File

@ -25,28 +25,28 @@ class MockCredentialsTelem(CredentialsTelem):
def test_credentials_generic_telemetry(TestTelem): def test_credentials_generic_telemetry(TestTelem):
mock_telemetry_messenger = MagicMock() mock_telemetry_messenger = MagicMock()
mock_credentials_store = MagicMock() mock_credentials_repository = MagicMock()
telemetry_messenger = CredentialsInterceptingTelemetryMessenger( telemetry_messenger = CredentialsInterceptingTelemetryMessenger(
mock_telemetry_messenger, mock_credentials_store mock_telemetry_messenger, mock_credentials_repository
) )
telemetry_messenger.send_telemetry(TestTelem()) telemetry_messenger.send_telemetry(TestTelem())
assert mock_telemetry_messenger.send_telemetry.called assert mock_telemetry_messenger.send_telemetry.called
assert not mock_credentials_store.add_credentials.called assert not mock_credentials_repository.add_credentials.called
def test_successful_intercepting_credentials_telemetry(): def test_successful_intercepting_credentials_telemetry():
mock_telemetry_messenger = MagicMock() mock_telemetry_messenger = MagicMock()
mock_credentials_store = MagicMock() mock_credentials_repository = MagicMock()
mock_empty_credentials_telem = MockCredentialsTelem(TELEM_CREDENTIALS) mock_empty_credentials_telem = MockCredentialsTelem(TELEM_CREDENTIALS)
telemetry_messenger = CredentialsInterceptingTelemetryMessenger( telemetry_messenger = CredentialsInterceptingTelemetryMessenger(
mock_telemetry_messenger, mock_credentials_store mock_telemetry_messenger, mock_credentials_repository
) )
telemetry_messenger.send_telemetry(mock_empty_credentials_telem) telemetry_messenger.send_telemetry(mock_empty_credentials_telem)
assert mock_telemetry_messenger.send_telemetry.called assert mock_telemetry_messenger.send_telemetry.called
assert mock_credentials_store.add_credentials.called assert mock_credentials_repository.add_credentials.called