diff --git a/README.md b/README.md index 29203e517..e0452e2f9 100644 --- a/README.md +++ b/README.md @@ -188,4 +188,4 @@ Dependency | License | Notes winbind | GPL-3 pyinstaller | GPL Celery | BSD - mimikatz | CC BY 4.0 | We use an altered version of mimikatz. Original: https://github.com/gentilkiwi/mimikatz + mimikatz | CC BY 4.0 | We use an altered version of mimikatz: https://github.com/guardicore/mimikatz diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py index c2eae0c33..b2ca2e6ae 100644 --- a/chaos_monkey/config.py +++ b/chaos_monkey/config.py @@ -4,6 +4,7 @@ from network.range import FixedRange, RelativeRange, ClassCRange from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger from abc import ABCMeta +from itertools import product import uuid import types @@ -13,7 +14,6 @@ GUID = str(uuid.getnode()) EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin') - def _cast_by_example(value, example): """ a method that casts a value to the type of the parameter given as example @@ -208,8 +208,13 @@ class Configuration(object): rdp_use_vbs_download = True # User and password dictionaries for exploits. - exploit_user_list = [] - exploit_password_list = [] + + @property + def exploit_user_password_pairs(self): + return product(self.exploit_user_list, self.exploit_password_list) + + exploit_user_list = ['Administrator', 'root', 'user'] + exploit_password_list = ["Password1!", "1234", "password", "12345678"] # smb/wmi exploiter smb_download_timeout = 300 # timeout in seconds diff --git a/chaos_monkey/exploit/smbexec.py b/chaos_monkey/exploit/smbexec.py index 072211c42..96fd8f956 100644 --- a/chaos_monkey/exploit/smbexec.py +++ b/chaos_monkey/exploit/smbexec.py @@ -64,12 +64,7 @@ class SmbExploiter(HostExploiter): LOG.info("Can't find suitable monkey executable for host %r", host) return False - config_users = self._config.exploit_user_list - config_passwords = self._config.exploit_password_list - user_password_pairs = [] - for user in config_users: - for password in config_passwords: - user_password_pairs.append((user, password)) + user_password_pairs = self._config.exploit_user_password_pairs exploited = False for user, password in user_password_pairs: diff --git a/chaos_monkey/exploit/sshexec.py b/chaos_monkey/exploit/sshexec.py index 42913e1f8..aa32549cb 100644 --- a/chaos_monkey/exploit/sshexec.py +++ b/chaos_monkey/exploit/sshexec.py @@ -42,14 +42,12 @@ class SSHExploiter(HostExploiter): is_open, _ = check_port_tcp(host.ip_addr, port) if not is_open: LOG.info("SSH port is closed on %r, skipping", host) - return False + return False - passwords = list(self._config.exploit_password_list[:]) - users = list(self._config.exploit_user_list) - user_pass = product(users,passwords) + user_password_pairs = self._config.exploit_user_password_pairs exploited = False - for user, curpass in user_pass: + for user, curpass in user_password_pairs: try: ssh.connect(host.ip_addr, username=user, diff --git a/chaos_monkey/exploit/win_ms08_067.py b/chaos_monkey/exploit/win_ms08_067.py index 48348d266..02f144851 100644 --- a/chaos_monkey/exploit/win_ms08_067.py +++ b/chaos_monkey/exploit/win_ms08_067.py @@ -233,7 +233,6 @@ class Ms08_067_Exploiter(HostExploiter): src_path, self._config.dropper_target_path) - # TODO: why are we doing this? Isn't that smbexec's job? if not remote_full_path: # try other passwords for administrator for password in self._config.exploit_password_list: diff --git a/chaos_monkey/exploit/wmiexec.py b/chaos_monkey/exploit/wmiexec.py index a0ea01d00..74b66eaa2 100644 --- a/chaos_monkey/exploit/wmiexec.py +++ b/chaos_monkey/exploit/wmiexec.py @@ -29,12 +29,7 @@ class WmiExploiter(HostExploiter): LOG.info("Can't find suitable monkey executable for host %r", host) return False - config_users = self._config.exploit_user_list - config_passwords = self._config.exploit_password_list - user_password_pairs = [] - for user in config_users: - for password in config_passwords: - user_password_pairs.append((user, password)) + user_password_pairs = self._config.exploit_user_password_pairs for user, password in user_password_pairs: LOG.debug("Attempting to connect %r using WMI with password '%s'", diff --git a/chaos_monkey/system_info/mimikatz_collector.py b/chaos_monkey/system_info/mimikatz_collector.py index a069a50ab..d7122d57a 100644 --- a/chaos_monkey/system_info/mimikatz_collector.py +++ b/chaos_monkey/system_info/mimikatz_collector.py @@ -69,10 +69,14 @@ class MimikatzCollector: """ Logon data structure returned from mimikatz. """ + + WINDOWS_MAX_USERNAME_PASS_LENGTH = 257 + LM_NTLM_HASH_LENGTH = 16 + _fields_ = \ [ - ("username", ctypes.c_wchar * 257), - ("password", ctypes.c_wchar * 257), - ("lm_hash", ctypes.c_byte * 16), - ("ntlm_hash", ctypes.c_byte * 16) + ("username", ctypes.c_wchar * WINDOWS_MAX_USERNAME_PASS_LENGTH), + ("password", ctypes.c_wchar * WINDOWS_MAX_USERNAME_PASS_LENGTH), + ("lm_hash", ctypes.c_byte * LM_NTLM_HASH_LENGTH), + ("ntlm_hash", ctypes.c_byte * LM_NTLM_HASH_LENGTH) ]