From 6aa2160f315d50bcea77754f0da11854b923ae32 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 14 Feb 2022 15:25:06 +0200 Subject: [PATCH] Agent: refactor mimikatz_cred_collector to credential collector --- .../credential_collectors/__init__.py | 6 +++ .../credential_components/nt_hashes.py | 9 ++++ .../credential_components/ntlm_hash.py | 8 ---- .../credential_components/password.py | 5 +-- .../credential_components/ssh_keypair.py | 3 +- .../credential_components/username.py | 5 +-- .../credential_collectors/credential_types.py | 2 +- .../mimikatz_cred_collector.py | 41 ++++++++++++------- 8 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 monkey/infection_monkey/credential_collectors/credential_components/nt_hashes.py delete mode 100644 monkey/infection_monkey/credential_collectors/credential_components/ntlm_hash.py diff --git a/monkey/infection_monkey/credential_collectors/__init__.py b/monkey/infection_monkey/credential_collectors/__init__.py index e69de29bb..4ec480246 100644 --- a/monkey/infection_monkey/credential_collectors/__init__.py +++ b/monkey/infection_monkey/credential_collectors/__init__.py @@ -0,0 +1,6 @@ +from .i_credential_collector import ICredentialCollector +from .credential_components.nt_hashes import NTHashes +from .credential_components.password import Password +from .credential_components.ssh_keypair import SSHKeypair +from .credential_components.username import Username +from .credentials import Credentials diff --git a/monkey/infection_monkey/credential_collectors/credential_components/nt_hashes.py b/monkey/infection_monkey/credential_collectors/credential_components/nt_hashes.py new file mode 100644 index 000000000..13acd83f6 --- /dev/null +++ b/monkey/infection_monkey/credential_collectors/credential_components/nt_hashes.py @@ -0,0 +1,9 @@ +from ..credential_types import CredentialTypes +from .i_credential_component import ICredentialComponent + + +class NTHashes(ICredentialComponent): + def __init__(self, ntlm_hash: str, lm_hash: str): + super().__init__( + type=CredentialTypes.NTLM_HASH, content={"ntlm_hash": ntlm_hash, "lm_hash": lm_hash} + ) diff --git a/monkey/infection_monkey/credential_collectors/credential_components/ntlm_hash.py b/monkey/infection_monkey/credential_collectors/credential_components/ntlm_hash.py deleted file mode 100644 index 35ddae49b..000000000 --- a/monkey/infection_monkey/credential_collectors/credential_components/ntlm_hash.py +++ /dev/null @@ -1,8 +0,0 @@ -from ..credential_types import CredentialTypes - -from .i_credential_component import ICredentialComponent - - -class NtlmHash(ICredentialComponent): - def __init__(self, content: dict): - super().__init__(type=CredentialTypes.NTLM_HASH, content=content) diff --git a/monkey/infection_monkey/credential_collectors/credential_components/password.py b/monkey/infection_monkey/credential_collectors/credential_components/password.py index fd5b71812..3691ee69a 100644 --- a/monkey/infection_monkey/credential_collectors/credential_components/password.py +++ b/monkey/infection_monkey/credential_collectors/credential_components/password.py @@ -1,8 +1,7 @@ from ..credential_types import CredentialTypes - from .i_credential_component import ICredentialComponent class Password(ICredentialComponent): - def __init__(self, content: dict): - super().__init__(type=CredentialTypes.PASSWORD, content=content) + def __init__(self, password: str): + super().__init__(type=CredentialTypes.PASSWORD, content={"password": password}) diff --git a/monkey/infection_monkey/credential_collectors/credential_components/ssh_keypair.py b/monkey/infection_monkey/credential_collectors/credential_components/ssh_keypair.py index 02390f781..09d0d2f01 100644 --- a/monkey/infection_monkey/credential_collectors/credential_components/ssh_keypair.py +++ b/monkey/infection_monkey/credential_collectors/credential_components/ssh_keypair.py @@ -1,8 +1,7 @@ from ..credential_types import CredentialTypes - from .i_credential_component import ICredentialComponent class SSHKeypair(ICredentialComponent): def __init__(self, content: dict): - super().__init__(type=CredentialTypes.KEYPAIR, content=content) + super().__init__(type=CredentialTypes.SSH_KEYPAIR, content=content) diff --git a/monkey/infection_monkey/credential_collectors/credential_components/username.py b/monkey/infection_monkey/credential_collectors/credential_components/username.py index 348a6df47..4ccf0ddea 100644 --- a/monkey/infection_monkey/credential_collectors/credential_components/username.py +++ b/monkey/infection_monkey/credential_collectors/credential_components/username.py @@ -1,8 +1,7 @@ from ..credential_types import CredentialTypes - from .i_credential_component import ICredentialComponent class Username(ICredentialComponent): - def __init__(self, content: dict): - super().__init__(type=CredentialTypes.USERNAME, content=content) + def __init__(self, username: str): + super().__init__(type=CredentialTypes.USERNAME, content={"username": username}) diff --git a/monkey/infection_monkey/credential_collectors/credential_types.py b/monkey/infection_monkey/credential_collectors/credential_types.py index 01b83797e..2354664a1 100644 --- a/monkey/infection_monkey/credential_collectors/credential_types.py +++ b/monkey/infection_monkey/credential_collectors/credential_types.py @@ -2,7 +2,7 @@ from enum import Enum class CredentialTypes(Enum): - KEYPAIR = 1 + SSH_KEYPAIR = 1 USERNAME = 2 PASSWORD = 3 NTLM_HASH = 4 diff --git a/monkey/infection_monkey/system_info/windows_cred_collector/mimikatz_cred_collector.py b/monkey/infection_monkey/system_info/windows_cred_collector/mimikatz_cred_collector.py index ab44d85ea..ff31667cf 100644 --- a/monkey/infection_monkey/system_info/windows_cred_collector/mimikatz_cred_collector.py +++ b/monkey/infection_monkey/system_info/windows_cred_collector/mimikatz_cred_collector.py @@ -1,25 +1,38 @@ from typing import List +from infection_monkey.credential_collectors import ( + Credentials, + ICredentialCollector, + NTHashes, + Password, + Username, +) from infection_monkey.system_info.windows_cred_collector import pypykatz_handler from infection_monkey.system_info.windows_cred_collector.windows_credentials import ( WindowsCredentials, ) -class MimikatzCredentialCollector(object): - @staticmethod - def get_creds(): +class MimikatzCredentialCollector(ICredentialCollector): + def collect_credentials(self) -> Credentials: creds = pypykatz_handler.get_windows_creds() - return MimikatzCredentialCollector.cred_list_to_cred_dict(creds) + return MimikatzCredentialCollector.to_credentials(creds) @staticmethod - def cred_list_to_cred_dict(creds: List[WindowsCredentials]): - cred_dict = {} - for cred in creds: - # TODO: This should be handled by the island, not the agent. There is already similar - # code in monkey_island/cc/models/report/report_dal.py. - # Lets not use "." and "$" in keys, because it will confuse mongo. - # Ideally we should refactor island not to use a dict and simply parse credential list. - key = cred.username.replace(".", ",").replace("$", "") - cred_dict.update({key: cred.to_dict()}) - return cred_dict + def to_credentials(win_creds: List[WindowsCredentials]) -> Credentials: + creds_obj = Credentials(identities=[], secrets=[]) + for win_cred in win_creds: + + if win_cred.username: + identity = Username(win_cred.username) + creds_obj.identities.append(identity) + + if win_cred.password: + password = Password(win_cred.password) + creds_obj.secrets.append(password) + + if win_cred.lm_hash or win_cred.ntlm_hash: + hashes = NTHashes(ntlm_hash=win_cred.ntlm_hash, lm_hash=win_cred.lm_hash) + creds_obj.secrets.append(hashes) + + return creds_obj