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.utils.decorators import request_cache
from .i_credentials_store import ICredentialsStore
from .i_propagation_credentials_repository import IPropagationCredentialsRepository
logger = logging.getLogger(__name__)
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):
self._stored_credentials = {
"exploit_user_list": set(),

View File

@ -5,12 +5,16 @@ from common.credentials import Credentials
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
def add_credentials(self, credentials_to_add: Iterable[Credentials]):
"""
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
@ -18,5 +22,4 @@ class ICredentialsStore(metaclass=abc.ABCMeta):
"""
Retrieves credentials from the store
: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.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_master import IMaster
from infection_monkey.i_puppet import IPuppet
@ -40,7 +40,7 @@ class AutomatedMaster(IMaster):
victim_host_factory: VictimHostFactory,
control_channel: IControlChannel,
local_network_interfaces: List[NetworkInterface],
credentials_store: ICredentialsStore,
credentials_store: IPropagationCredentialsRepository,
):
self._current_depth = current_depth
self._puppet = puppet

View File

@ -17,7 +17,10 @@ from infection_monkey.credential_collectors import (
MimikatzCredentialCollector,
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.hadoop import HadoopExploiter
from infection_monkey.exploit.log4shell import Log4ShellExploiter
@ -195,7 +198,7 @@ class InfectionMonkey:
control_channel = ControlChannel(
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)
@ -226,7 +229,7 @@ class InfectionMonkey:
return local_network_interfaces
def _build_puppet(self, credentials_store: ICredentialsStore) -> IPuppet:
def _build_puppet(self, credentials_store: IPropagationCredentialsRepository) -> IPuppet:
puppet = Puppet()
puppet.load_plugin(

View File

@ -1,6 +1,6 @@
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.i_telem import ITelem
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):
def __init__(
self, telemetry_messenger: ITelemetryMessenger, credentials_store: ICredentialsStore
self,
telemetry_messenger: ITelemetryMessenger,
credentials_store: IPropagationCredentialsRepository,
):
self._telemetry_messenger = telemetry_messenger
self._credentials_store = credentials_store
@ -23,7 +25,7 @@ class CredentialsInterceptingTelemetryMessenger(ITelemetryMessenger):
def _send_telemetry(
telemetry: ITelem,
telemetry_messenger: ITelemetryMessenger,
credentials_store: ICredentialsStore,
credentials_store: IPropagationCredentialsRepository,
):
telemetry_messenger.send_telemetry(telemetry)
@ -32,7 +34,7 @@ def _send_telemetry(
def _(
telemetry: CredentialsTelem,
telemetry_messenger: ITelemetryMessenger,
credentials_store: ICredentialsStore,
credentials_store: IPropagationCredentialsRepository,
):
credentials_store.add_credentials(telemetry.credentials)
telemetry_messenger.send_telemetry(telemetry)

View File

@ -1,11 +1,10 @@
from datetime import datetime
from enum import Enum
from json import loads
from json import JSONEncoder, dumps, loads
from typing import Any
import bson
from flask import make_response
from flask.json import JSONEncoder, dumps
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 infection_monkey.credential_store import AggregatingCredentialsStore
from infection_monkey.credential_repository import AggregatingPropagationCredentialsRepository
CONTROL_CHANNEL_CREDENTIALS = PROPAGATION_CREDENTIALS
TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS = {
@ -67,24 +67,24 @@ STOLEN_SSH_KEYS_CREDENTIALS = [
@pytest.fixture
def aggregating_credentials_store() -> AggregatingCredentialsStore:
def aggregating_credentials_repository() -> AggregatingPropagationCredentialsRepository:
control_channel = MagicMock()
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())
def test_get_credentials_from_store(aggregating_credentials_store, key):
actual_stored_credentials = aggregating_credentials_store.get_credentials()
def test_get_credentials_from_repository(aggregating_credentials_repository, key):
actual_stored_credentials = aggregating_credentials_repository.get_credentials()
assert actual_stored_credentials[key] == TRANSFORMED_CONTROL_CHANNEL_CREDENTIALS[key]
def test_add_credentials_to_store(aggregating_credentials_store):
aggregating_credentials_store.add_credentials(STOLEN_CREDENTIALS)
aggregating_credentials_store.add_credentials(STOLEN_SSH_KEYS_CREDENTIALS)
def test_add_credentials_to_repository(aggregating_credentials_repository):
aggregating_credentials_repository.add_credentials(STOLEN_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(
[
@ -113,9 +113,9 @@ def test_add_credentials_to_store(aggregating_credentials_store):
def test_all_keys_if_credentials_empty():
control_channel = MagicMock()
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))
assert "exploit_user_list" in actual_stored_credentials

View File

@ -25,28 +25,28 @@ class MockCredentialsTelem(CredentialsTelem):
def test_credentials_generic_telemetry(TestTelem):
mock_telemetry_messenger = MagicMock()
mock_credentials_store = MagicMock()
mock_credentials_repository = MagicMock()
telemetry_messenger = CredentialsInterceptingTelemetryMessenger(
mock_telemetry_messenger, mock_credentials_store
mock_telemetry_messenger, mock_credentials_repository
)
telemetry_messenger.send_telemetry(TestTelem())
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():
mock_telemetry_messenger = MagicMock()
mock_credentials_store = MagicMock()
mock_credentials_repository = MagicMock()
mock_empty_credentials_telem = MockCredentialsTelem(TELEM_CREDENTIALS)
telemetry_messenger = CredentialsInterceptingTelemetryMessenger(
mock_telemetry_messenger, mock_credentials_store
mock_telemetry_messenger, mock_credentials_repository
)
telemetry_messenger.send_telemetry(mock_empty_credentials_telem)
assert mock_telemetry_messenger.send_telemetry.called
assert mock_credentials_store.add_credentials.called
assert mock_credentials_repository.add_credentials.called