diff --git a/envs/__init__.py b/envs/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/.gitignore b/envs/monkey_zoo/.gitignore new file mode 100644 index 000000000..333c1e910 --- /dev/null +++ b/envs/monkey_zoo/.gitignore @@ -0,0 +1 @@ +logs/ diff --git a/envs/monkey_zoo/__init__.py b/envs/monkey_zoo/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/README.md b/envs/monkey_zoo/blackbox/README.md new file mode 100644 index 000000000..12b33ebce --- /dev/null +++ b/envs/monkey_zoo/blackbox/README.md @@ -0,0 +1,5 @@ +# Automatic blackbox tests +### Prerequisites +1. Download google sdk: https://cloud.google.com/sdk/docs/ +2. Download service account key for MonkeyZoo project (if you deployed MonkeyZoo via terraform scripts then you already have it). +GCP console -> IAM -> service accounts(you can use the same key used to authenticate terraform scripts) diff --git a/envs/monkey_zoo/blackbox/__init__.py b/envs/monkey_zoo/blackbox/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/analyzers/__init__.py b/envs/monkey_zoo/blackbox/analyzers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/analyzers/analyzer_log.py b/envs/monkey_zoo/blackbox/analyzers/analyzer_log.py new file mode 100644 index 000000000..f97418813 --- /dev/null +++ b/envs/monkey_zoo/blackbox/analyzers/analyzer_log.py @@ -0,0 +1,17 @@ +LOG_INIT_MESSAGE = "Analysis didn't run." + + +class AnalyzerLog(object): + + def __init__(self, analyzer_name): + self.contents = LOG_INIT_MESSAGE + self.name = analyzer_name + + def clear(self): + self.contents = "" + + def add_entry(self, message): + self.contents = "{}\n{}".format(self.contents, message) + + def get_contents(self): + return "{}: {}\n".format(self.name, self.contents) diff --git a/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py b/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py new file mode 100644 index 000000000..491b534b8 --- /dev/null +++ b/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py @@ -0,0 +1,24 @@ +from envs.monkey_zoo.blackbox.analyzers.analyzer_log import AnalyzerLog + + +class CommunicationAnalyzer(object): + + def __init__(self, island_client, machine_ips): + self.island_client = island_client + self.machine_ips = machine_ips + self.log = AnalyzerLog(self.__class__.__name__) + + def analyze_test_results(self): + self.log.clear() + all_monkeys_communicated = True + for machine_ip in self.machine_ips: + if not self.did_monkey_communicate_back(machine_ip): + self.log.add_entry("Monkey from {} didn't communicate back".format(machine_ip)) + all_monkeys_communicated = False + else: + self.log.add_entry("Monkey from {} communicated back".format(machine_ip)) + return all_monkeys_communicated + + def did_monkey_communicate_back(self, machine_ip): + query = {'ip_addresses': {'$elemMatch': {'$eq': machine_ip}}} + return len(self.island_client.find_monkeys_in_db(query)) > 0 diff --git a/envs/monkey_zoo/blackbox/conftest.py b/envs/monkey_zoo/blackbox/conftest.py new file mode 100644 index 000000000..13aabf5b6 --- /dev/null +++ b/envs/monkey_zoo/blackbox/conftest.py @@ -0,0 +1,11 @@ +import pytest + + +def pytest_addoption(parser): + parser.addoption("--island", action="store", default="", + help="Specify the Monkey Island address (host+port).") + + +@pytest.fixture(scope='module') +def island(request): + return request.config.getoption("--island") diff --git a/envs/monkey_zoo/blackbox/island_client/__init__.py b/envs/monkey_zoo/blackbox/island_client/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/island_client/island_config_parser.py b/envs/monkey_zoo/blackbox/island_client/island_config_parser.py new file mode 100644 index 000000000..948b58310 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_client/island_config_parser.py @@ -0,0 +1,18 @@ +import json +import os + + +class IslandConfigParser(object): + + def __init__(self, config_filename): + self.config_raw = open(IslandConfigParser.get_conf_file_path(config_filename), 'r').read() + self.config_json = json.loads(self.config_raw) + + def get_ips_of_targets(self): + return self.config_json['basic_network']['general']['subnet_scan_list'] + + @staticmethod + def get_conf_file_path(conf_file_name): + return os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "island_configs", + conf_file_name) diff --git a/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py b/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py new file mode 100644 index 000000000..479c41bab --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_client/monkey_island_client.py @@ -0,0 +1,87 @@ +from time import sleep +import json + +import logging +from bson import json_util + +from envs.monkey_zoo.blackbox.island_client.monkey_island_requests import MonkeyIslandRequests + +SLEEP_BETWEEN_REQUESTS_SECONDS = 0.5 +MONKEY_TEST_ENDPOINT = 'api/test/monkey' +LOG_TEST_ENDPOINT = 'api/test/log' +LOGGER = logging.getLogger(__name__) + + +def avoid_race_condition(func): + sleep(SLEEP_BETWEEN_REQUESTS_SECONDS) + return func + + +class MonkeyIslandClient(object): + def __init__(self, server_address): + self.requests = MonkeyIslandRequests(server_address) + + def get_api_status(self): + return self.requests.get("api") + + @avoid_race_condition + def import_config(self, config_contents): + _ = self.requests.post("api/configuration/island", data=config_contents) + + @avoid_race_condition + def run_monkey_local(self): + response = self.requests.post_json("api/local-monkey", dict_data={"action": "run"}) + if MonkeyIslandClient.monkey_ran_successfully(response): + LOGGER.info("Running the monkey.") + else: + LOGGER.error("Failed to run the monkey.") + assert False + + @staticmethod + def monkey_ran_successfully(response): + return response.ok and json.loads(response.content)['is_running'] + + @avoid_race_condition + def kill_all_monkeys(self): + if self.requests.get("api", {"action": "killall"}).ok: + LOGGER.info("Killing all monkeys after the test.") + else: + LOGGER.error("Failed to kill all monkeys.") + assert False + + @avoid_race_condition + def reset_env(self): + if self.requests.get("api", {"action": "reset"}).ok: + LOGGER.info("Resetting environment after the test.") + else: + LOGGER.error("Failed to reset the environment.") + assert False + + def find_monkeys_in_db(self, query): + if query is None: + raise TypeError + response = self.requests.get(MONKEY_TEST_ENDPOINT, + MonkeyIslandClient.form_find_query_for_request(query)) + return MonkeyIslandClient.get_test_query_results(response) + + def get_all_monkeys_from_db(self): + response = self.requests.get(MONKEY_TEST_ENDPOINT, + MonkeyIslandClient.form_find_query_for_request(None)) + return MonkeyIslandClient.get_test_query_results(response) + + def find_log_in_db(self, query): + response = self.requests.get(LOG_TEST_ENDPOINT, + MonkeyIslandClient.form_find_query_for_request(query)) + return MonkeyIslandClient.get_test_query_results(response) + + @staticmethod + def form_find_query_for_request(query): + return {'find_query': json_util.dumps(query)} + + @staticmethod + def get_test_query_results(response): + return json.loads(response.content)['results'] + + def is_all_monkeys_dead(self): + query = {'dead': False} + return len(self.find_monkeys_in_db(query)) == 0 diff --git a/envs/monkey_zoo/blackbox/island_client/monkey_island_requests.py b/envs/monkey_zoo/blackbox/island_client/monkey_island_requests.py new file mode 100644 index 000000000..1f9fc2642 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_client/monkey_island_requests.py @@ -0,0 +1,48 @@ +import requests + +# SHA3-512 of '1234567890!@#$%^&*()_nothing_up_my_sleeve_1234567890!@#$%^&*()' +import logging + +NO_AUTH_CREDS = '55e97c9dcfd22b8079189ddaeea9bce8125887e3237b800c6176c9afa80d2062' \ + '8d2c8d0b1538d2208c1444ac66535b764a3d902b35e751df3faec1e477ed3557' +LOGGER = logging.getLogger(__name__) + + +class MonkeyIslandRequests(object): + def __init__(self, server_address): + self.addr = "https://{IP}/".format(IP=server_address) + self.token = self.try_get_jwt_from_server() + + def try_get_jwt_from_server(self): + try: + return self.get_jwt_from_server() + except requests.ConnectionError: + LOGGER.error("Unable to connect to island, aborting!") + assert False + + def get_jwt_from_server(self): + resp = requests.post(self.addr + "api/auth", + json={"username": NO_AUTH_CREDS, "password": NO_AUTH_CREDS}, + verify=False) + return resp.json()["access_token"] + + def get(self, url, data=None): + return requests.get(self.addr + url, + headers=self.get_jwt_header(), + params=data, + verify=False) + + def post(self, url, data): + return requests.post(self.addr + url, + data=data, + headers=self.get_jwt_header(), + verify=False) + + def post_json(self, url, dict_data): + return requests.post(self.addr + url, + json=dict_data, + headers=self.get_jwt_header(), + verify=False) + + def get_jwt_header(self): + return {"Authorization": "JWT " + self.token} diff --git a/envs/monkey_zoo/blackbox/island_configs/ELASTIC.conf b/envs/monkey_zoo/blackbox/island_configs/ELASTIC.conf new file mode 100644 index 000000000..0a81ea700 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/ELASTIC.conf @@ -0,0 +1,184 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.4", + "10.2.2.5" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "ElasticGroovyExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/HADOOP.conf b/envs/monkey_zoo/blackbox/island_configs/HADOOP.conf new file mode 100644 index 000000000..1b55557a9 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/HADOOP.conf @@ -0,0 +1,186 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.3", + "10.2.2.10" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "HadoopExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [ + "e1c0dc690821c13b10a41dccfc72e43a" + ], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/MSSQL.conf b/envs/monkey_zoo/blackbox/island_configs/MSSQL.conf new file mode 100644 index 000000000..dc3332ed6 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/MSSQL.conf @@ -0,0 +1,183 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "Xk8VDTsC", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.16" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "MSSQLExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/SHELLSHOCK.conf b/envs/monkey_zoo/blackbox/island_configs/SHELLSHOCK.conf new file mode 100644 index 000000000..7fd857e65 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/SHELLSHOCK.conf @@ -0,0 +1,183 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.38" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "ShellShockExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/SMB_MIMIKATZ.conf b/envs/monkey_zoo/blackbox/island_configs/SMB_MIMIKATZ.conf new file mode 100644 index 000000000..b5001025f --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/SMB_MIMIKATZ.conf @@ -0,0 +1,182 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "Ivrrw5zEzs" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.44", + "10.2.2.15" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "SmbExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/SMB_PTH.conf b/envs/monkey_zoo/blackbox/island_configs/SMB_PTH.conf new file mode 100644 index 000000000..d17e283c8 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/SMB_PTH.conf @@ -0,0 +1,180 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.15" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "SmbExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [ "f7e457346f7743daece17258667c936d" ], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/SSH.conf b/envs/monkey_zoo/blackbox/island_configs/SSH.conf new file mode 100644 index 000000000..e96894111 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/SSH.conf @@ -0,0 +1,192 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "12345678", + "^NgDvY59~8" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.41", + "10.2.2.42" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "SmbExploiter", + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf b/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf new file mode 100644 index 000000000..30bb135e4 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf @@ -0,0 +1,193 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.9", + "10.2.2.11" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "SmbExploiter", + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf b/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf new file mode 100644 index 000000000..a7e84f1b8 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf @@ -0,0 +1,194 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "3Q=(Ge(+&w]*", + "`))jU7L(w}", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 3, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.32", + "10.2.1.10", + "10.2.0.11" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "SmbExploiter", + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 60, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/WEBLOGIC.conf b/envs/monkey_zoo/blackbox/island_configs/WEBLOGIC.conf new file mode 100644 index 000000000..b86b2b566 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/WEBLOGIC.conf @@ -0,0 +1,184 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.18", + "10.2.2.19" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "WebLogicExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/WMI_MIMIKATZ.conf b/envs/monkey_zoo/blackbox/island_configs/WMI_MIMIKATZ.conf new file mode 100644 index 000000000..1498530d5 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/WMI_MIMIKATZ.conf @@ -0,0 +1,190 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!", + "Ivrrw5zEzs" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.44", + "10.2.2.15" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/island_configs/WMI_PTH.conf b/envs/monkey_zoo/blackbox/island_configs/WMI_PTH.conf new file mode 100644 index 000000000..1ac0a6c3d --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_configs/WMI_PTH.conf @@ -0,0 +1,188 @@ +{ + "basic": { + "credentials": { + "exploit_password_list": [ + "Password1!" + ], + "exploit_user_list": [ + "Administrator", + "m0nk3y", + "user" + ] + }, + "general": { + "should_exploit": true + } + }, + "basic_network": { + "general": { + "blocked_ips": [], + "depth": 2, + "local_network_scan": false, + "subnet_scan_list": [ + "10.2.2.15" + ] + }, + "network_analysis": { + "inaccessible_subnets": [] + } + }, + "cnc": { + "servers": { + "command_servers": [ + "10.2.2.251:5000" + ], + "current_server": "10.2.2.251:5000", + "internet_services": [ + "monkey.guardicore.com", + "www.google.com" + ] + } + }, + "exploits": { + "general": { + "exploiter_classes": [ + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter" + ], + "skip_exploit_if_file_exist": false + }, + "ms08_067": { + "ms08_067_exploit_attempts": 5, + "remote_user_pass": "Password1!", + "user_to_add": "Monkey_IUSER_SUPPORT" + }, + "rdp_grinder": { + "rdp_use_vbs_download": true + }, + "sambacry": { + "sambacry_folder_paths_to_guess": [ + "/", + "/mnt", + "/tmp", + "/storage", + "/export", + "/share", + "/shares", + "/home" + ], + "sambacry_shares_not_to_check": [ + "IPC$", + "print$" + ], + "sambacry_trigger_timeout": 5 + }, + "smb_service": { + "smb_download_timeout": 300, + "smb_service_name": "InfectionMonkey" + } + }, + "internal": { + "classes": { + "finger_classes": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + }, + "dropper": { + "dropper_date_reference_path_linux": "/bin/sh", + "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", + "dropper_set_date": true, + "dropper_target_path_linux": "/tmp/monkey", + "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", + "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", + "dropper_try_move_first": true + }, + "exploits": { + "exploit_lm_hash_list": [], + "exploit_ntlm_hash_list": [ "f7e457346f7743daece17258667c936d" ], + "exploit_ssh_keys": [] + }, + "general": { + "keep_tunnel_open_time": 1, + "monkey_dir_name": "monkey_dir", + "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" + }, + "kill_file": { + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not" + }, + "logging": { + "dropper_log_path_linux": "/tmp/user-1562", + "dropper_log_path_windows": "%temp%\\~df1562.tmp", + "monkey_log_path_linux": "/tmp/user-1563", + "monkey_log_path_windows": "%temp%\\~df1563.tmp", + "send_log_to_server": true + } + }, + "monkey": { + "behaviour": { + "PBA_linux_filename": "", + "PBA_windows_filename": "", + "custom_PBA_linux_cmd": "", + "custom_PBA_windows_cmd": "", + "self_delete_in_cleanup": true, + "serialize_config": false, + "use_file_logging": true + }, + "general": { + "alive": true, + "post_breach_actions": [] + }, + "life_cycle": { + "max_iterations": 1, + "retry_failed_explotation": true, + "timeout_between_iterations": 100, + "victims_max_exploit": 7, + "victims_max_find": 30 + }, + "system_info": { + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true + } + }, + "network": { + "ping_scanner": { + "ping_scan_timeout": 1000 + }, + "tcp_scanner": { + "HTTP_PORTS": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "tcp_scan_get_banner": true, + "tcp_scan_interval": 0, + "tcp_scan_timeout": 3000, + "tcp_target_ports": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001 + ] + } + } +} diff --git a/envs/monkey_zoo/blackbox/log_handlers/__init__.py b/envs/monkey_zoo/blackbox/log_handlers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/log_handlers/monkey_log.py b/envs/monkey_zoo/blackbox/log_handlers/monkey_log.py new file mode 100644 index 000000000..091be570a --- /dev/null +++ b/envs/monkey_zoo/blackbox/log_handlers/monkey_log.py @@ -0,0 +1,38 @@ +import os + +import logging +from bson import ObjectId + +LOGGER = logging.getLogger(__name__) + + +class MonkeyLog(object): + def __init__(self, monkey, log_dir_path): + self.monkey = monkey + self.log_dir_path = log_dir_path + + def download_log(self, island_client): + log = island_client.find_log_in_db({'monkey_id': ObjectId(self.monkey['id'])}) + if not log: + LOGGER.error("Log for monkey {} not found".format(self.monkey['ip_addresses'][0])) + return False + else: + self.write_log_to_file(log) + return True + + def write_log_to_file(self, log): + with open(self.get_log_path_for_monkey(self.monkey), 'w') as log_file: + log_file.write(MonkeyLog.parse_log(log)) + + @staticmethod + def parse_log(log): + log = log.strip('"') + log = log.replace("\\n", "\n ") + return log + + @staticmethod + def get_filename_for_monkey_log(monkey): + return "{}.txt".format(monkey['ip_addresses'][0]) + + def get_log_path_for_monkey(self, monkey): + return os.path.join(self.log_dir_path, MonkeyLog.get_filename_for_monkey_log(monkey)) diff --git a/envs/monkey_zoo/blackbox/log_handlers/monkey_log_parser.py b/envs/monkey_zoo/blackbox/log_handlers/monkey_log_parser.py new file mode 100644 index 000000000..d12db4f58 --- /dev/null +++ b/envs/monkey_zoo/blackbox/log_handlers/monkey_log_parser.py @@ -0,0 +1,32 @@ +import re + + +class MonkeyLogParser(object): + + def __init__(self, log_path): + self.log_path = log_path + self.log_contents = self.read_log() + + def read_log(self): + with open(self.log_path, 'r') as log: + return log.read() + + def print_errors(self): + print("Errors:") + for error_line in MonkeyLogParser.get_errors(self.log_contents): + print(error_line) + + @staticmethod + def get_errors(log_contents): + searcher = re.compile(r"^.*:ERROR].*$", re.MULTILINE) + return searcher.findall(log_contents) + + def print_warnings(self): + print("Warnings:") + for warning_line in MonkeyLogParser.get_warnings(self.log_contents): + print(warning_line) + + @staticmethod + def get_warnings(log_contents): + searcher = re.compile(r"^.*:WARNING].*$", re.MULTILINE) + return searcher.findall(log_contents) diff --git a/envs/monkey_zoo/blackbox/log_handlers/monkey_logs_downloader.py b/envs/monkey_zoo/blackbox/log_handlers/monkey_logs_downloader.py new file mode 100644 index 000000000..dbed46780 --- /dev/null +++ b/envs/monkey_zoo/blackbox/log_handlers/monkey_logs_downloader.py @@ -0,0 +1,26 @@ +import logging + +from envs.monkey_zoo.blackbox.log_handlers.monkey_log import MonkeyLog + +LOGGER = logging.getLogger(__name__) + + +class MonkeyLogsDownloader(object): + + def __init__(self, island_client, log_dir_path): + self.island_client = island_client + self.log_dir_path = log_dir_path + self.monkey_log_paths = [] + + def download_monkey_logs(self): + LOGGER.info("Downloading each monkey log.") + all_monkeys = self.island_client.get_all_monkeys_from_db() + for monkey in all_monkeys: + downloaded_log_path = self._download_monkey_log(monkey) + if downloaded_log_path: + self.monkey_log_paths.append(downloaded_log_path) + + def _download_monkey_log(self, monkey): + log_handler = MonkeyLog(monkey, self.log_dir_path) + download_successful = log_handler.download_log(self.island_client) + return log_handler.get_log_path_for_monkey(monkey) if download_successful else None diff --git a/envs/monkey_zoo/blackbox/log_handlers/test_logs_handler.py b/envs/monkey_zoo/blackbox/log_handlers/test_logs_handler.py new file mode 100644 index 000000000..fb1c39ac2 --- /dev/null +++ b/envs/monkey_zoo/blackbox/log_handlers/test_logs_handler.py @@ -0,0 +1,50 @@ +import os +import shutil + +import logging + +from envs.monkey_zoo.blackbox.log_handlers.monkey_log_parser import MonkeyLogParser +from envs.monkey_zoo.blackbox.log_handlers.monkey_logs_downloader import MonkeyLogsDownloader + +LOG_DIR_NAME = 'logs' +LOGGER = logging.getLogger(__name__) + + +class TestLogsHandler(object): + def __init__(self, test_name, island_client, log_dir_path): + self.test_name = test_name + self.island_client = island_client + self.log_dir_path = os.path.join(log_dir_path, self.test_name) + + def parse_test_logs(self): + log_paths = self.download_logs() + if not log_paths: + LOGGER.error("No logs were downloaded. Maybe no monkeys were ran " + "or early exception prevented log download?") + return + TestLogsHandler.parse_logs(log_paths) + + def download_logs(self): + self.try_create_log_dir_for_test() + downloader = MonkeyLogsDownloader(self.island_client, self.log_dir_path) + downloader.download_monkey_logs() + return downloader.monkey_log_paths + + def try_create_log_dir_for_test(self): + try: + os.mkdir(self.log_dir_path) + except Exception as e: + LOGGER.error("Can't create a dir for test logs: {}".format(e)) + + @staticmethod + def delete_log_folder_contents(log_dir_path): + shutil.rmtree(log_dir_path, ignore_errors=True) + os.mkdir(log_dir_path) + + @staticmethod + def parse_logs(log_paths): + for log_path in log_paths: + print("Info from log at {}".format(log_path)) + log_parser = MonkeyLogParser(log_path) + log_parser.print_errors() + log_parser.print_warnings() diff --git a/envs/monkey_zoo/blackbox/pytest.ini b/envs/monkey_zoo/blackbox/pytest.ini new file mode 100644 index 000000000..79a6b4a32 --- /dev/null +++ b/envs/monkey_zoo/blackbox/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +log_cli = 1 +log_cli_level = INFO +log_cli_format = %(asctime)s [%(levelname)s] %(message)s +log_cli_date_format=%H:%M:%S diff --git a/envs/monkey_zoo/blackbox/requirements.txt b/envs/monkey_zoo/blackbox/requirements.txt new file mode 100644 index 000000000..0e6bd0ea3 --- /dev/null +++ b/envs/monkey_zoo/blackbox/requirements.txt @@ -0,0 +1,2 @@ +pytest +unittest diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py new file mode 100644 index 000000000..4ce4603aa --- /dev/null +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -0,0 +1,109 @@ +import os +import logging + +import pytest +from time import sleep + +from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient +from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer +from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser +from envs.monkey_zoo.blackbox.utils import gcp_machine_handlers +from envs.monkey_zoo.blackbox.tests.basic_test import BasicTest +from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler + +DEFAULT_TIMEOUT_SECONDS = 5*60 +MACHINE_BOOTUP_WAIT_SECONDS = 30 +GCP_TEST_MACHINE_LIST = ['sshkeys-11', 'sshkeys-12', 'elastic-4', 'elastic-5', 'haddop-2-v3', 'hadoop-3', 'mssql-16', + 'mimikatz-14', 'mimikatz-15', 'final-test-struts2-23', 'final-test-struts2-24', + 'tunneling-9', 'tunneling-10', 'tunneling-11', 'weblogic-18', 'weblogic-19', 'shellshock-8'] +LOG_DIR_PATH = "./logs" +LOGGER = logging.getLogger(__name__) + + +@pytest.fixture(autouse=True, scope='session') +def GCPHandler(request): + GCPHandler = gcp_machine_handlers.GCPHandler() + GCPHandler.start_machines(" ".join(GCP_TEST_MACHINE_LIST)) + wait_machine_bootup() + + def fin(): + GCPHandler.stop_machines(" ".join(GCP_TEST_MACHINE_LIST)) + + request.addfinalizer(fin) + + +@pytest.fixture(autouse=True, scope='session') +def delete_logs(): + LOGGER.info("Deleting monkey logs before new tests.") + TestLogsHandler.delete_log_folder_contents(TestMonkeyBlackbox.get_log_dir_path()) + + +def wait_machine_bootup(): + sleep(MACHINE_BOOTUP_WAIT_SECONDS) + + +@pytest.fixture(scope='class') +def island_client(island): + island_client_object = MonkeyIslandClient(island) + island_client_object.reset_env() + yield island_client_object + + +@pytest.mark.usefixtures('island_client') +# noinspection PyUnresolvedReferences +class TestMonkeyBlackbox(object): + + @staticmethod + def run_basic_test(island_client, conf_filename, test_name, timeout_in_seconds=DEFAULT_TIMEOUT_SECONDS): + config_parser = IslandConfigParser(conf_filename) + analyzer = CommunicationAnalyzer(island_client, config_parser.get_ips_of_targets()) + log_handler = TestLogsHandler(test_name, island_client, TestMonkeyBlackbox.get_log_dir_path()) + BasicTest(test_name, + island_client, + config_parser, + [analyzer], + timeout_in_seconds, + log_handler).run() + + @staticmethod + def get_log_dir_path(): + return os.path.abspath(LOG_DIR_PATH) + + def test_server_online(self, island_client): + assert island_client.get_api_status() is not None + + def test_ssh_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "SSH.conf", "SSH_exploiter_and_keys") + + def test_hadoop_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "HADOOP.conf", "Hadoop_exploiter", 6*60) + + def test_mssql_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "MSSQL.conf", "MSSQL_exploiter") + + def test_smb_and_mimikatz_exploiters(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "SMB_MIMIKATZ.conf", "SMB_exploiter_mimikatz") + + def test_smb_pth(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "SMB_PTH.conf", "SMB_PTH") + + def test_elastic_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "ELASTIC.conf", "Elastic_exploiter") + + def test_struts_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "STRUTS2.conf", "Strtuts2_exploiter") + + def test_weblogic_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "WEBLOGIC.conf", "Weblogic_exploiter") + + def test_shellshock_exploiter(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "SHELLSHOCK.conf", "Shellschock_exploiter") + + def test_tunneling(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "TUNNELING.conf", "Tunneling_exploiter", 10*60) + + def test_wmi_and_mimikatz_exploiters(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "WMI_MIMIKATZ.conf", "WMI_exploiter,_mimikatz") + + def test_wmi_pth(self, island_client): + TestMonkeyBlackbox.run_basic_test(island_client, "WMI_PTH.conf", "WMI_PTH") diff --git a/envs/monkey_zoo/blackbox/tests/__init__.py b/envs/monkey_zoo/blackbox/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/tests/basic_test.py b/envs/monkey_zoo/blackbox/tests/basic_test.py new file mode 100644 index 000000000..8e9066a8a --- /dev/null +++ b/envs/monkey_zoo/blackbox/tests/basic_test.py @@ -0,0 +1,94 @@ +from time import sleep + +import logging + +from envs.monkey_zoo.blackbox.utils.test_timer import TestTimer + +MAX_TIME_FOR_MONKEYS_TO_DIE = 5 * 60 +WAIT_TIME_BETWEEN_REQUESTS = 10 +TIME_FOR_MONKEY_PROCESS_TO_FINISH = 40 +DELAY_BETWEEN_ANALYSIS = 3 +LOGGER = logging.getLogger(__name__) + + +class BasicTest(object): + + def __init__(self, name, island_client, config_parser, analyzers, timeout, log_handler): + self.name = name + self.island_client = island_client + self.config_parser = config_parser + self.analyzers = analyzers + self.timeout = timeout + self.log_handler = log_handler + + def run(self): + self.island_client.import_config(self.config_parser.config_raw) + self.print_test_starting_info() + try: + self.island_client.run_monkey_local() + self.test_until_timeout() + finally: + self.island_client.kill_all_monkeys() + self.wait_until_monkeys_die() + self.wait_for_monkey_process_to_finish() + self.parse_logs() + self.island_client.reset_env() + + def print_test_starting_info(self): + LOGGER.info("Started {} test".format(self.name)) + LOGGER.info("Machines participating in test:") + LOGGER.info(" ".join(self.config_parser.get_ips_of_targets())) + print("") + + def test_until_timeout(self): + timer = TestTimer(self.timeout) + while not timer.is_timed_out(): + if self.all_analyzers_pass(): + self.log_success(timer) + return + sleep(DELAY_BETWEEN_ANALYSIS) + self.log_failure(timer) + assert False + + def log_success(self, timer): + LOGGER.info(self.get_analyzer_logs()) + LOGGER.info("{} test passed, time taken: {:.1f} seconds.".format(self.name, timer.get_time_taken())) + + def log_failure(self, timer): + LOGGER.info(self.get_analyzer_logs()) + LOGGER.error("{} test failed because of timeout. Time taken: {:.1f} seconds.".format(self.name, + timer.get_time_taken())) + + def all_analyzers_pass(self): + for analyzer in self.analyzers: + if not analyzer.analyze_test_results(): + return False + return True + + def get_analyzer_logs(self): + log = "" + for analyzer in self.analyzers: + log += "\n" + analyzer.log.get_contents() + return log + + def wait_until_monkeys_die(self): + time_passed = 0 + while not self.island_client.is_all_monkeys_dead() and time_passed < MAX_TIME_FOR_MONKEYS_TO_DIE: + sleep(WAIT_TIME_BETWEEN_REQUESTS) + time_passed += WAIT_TIME_BETWEEN_REQUESTS + if time_passed > MAX_TIME_FOR_MONKEYS_TO_DIE: + LOGGER.error("Some monkeys didn't die after the test, failing") + assert False + + def parse_logs(self): + LOGGER.info("\nParsing test logs:") + self.log_handler.parse_test_logs() + + @staticmethod + def wait_for_monkey_process_to_finish(): + """ + There is a time period when monkey is set to dead, but the process is still closing. + If we try to launch monkey during that time window monkey will fail to start, that's + why test needs to wait a bit even after all monkeys are dead. + """ + sleep(TIME_FOR_MONKEY_PROCESS_TO_FINISH) diff --git a/envs/monkey_zoo/blackbox/utils/__init__.py b/envs/monkey_zoo/blackbox/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/envs/monkey_zoo/blackbox/utils/gcp_machine_handlers.py b/envs/monkey_zoo/blackbox/utils/gcp_machine_handlers.py new file mode 100644 index 000000000..ac9e63d3e --- /dev/null +++ b/envs/monkey_zoo/blackbox/utils/gcp_machine_handlers.py @@ -0,0 +1,49 @@ +import subprocess + +import logging + +LOGGER = logging.getLogger(__name__) + + +class GCPHandler(object): + + AUTHENTICATION_COMMAND = "gcloud auth activate-service-account --key-file=%s" + SET_PROPERTY_PROJECT = "gcloud config set project %s" + MACHINE_STARTING_COMMAND = "gcloud compute instances start %s --zone=%s" + MACHINE_STOPPING_COMMAND = "gcloud compute instances stop %s --zone=%s" + + def __init__(self, key_path="../gcp_keys/gcp_key.json", zone="europe-west3-a", project_id="guardicore-22050661"): + self.zone = zone + try: + # pass the key file to gcp + subprocess.call(GCPHandler.get_auth_command(key_path), shell=True) + LOGGER.info("GCP Handler passed key") + # set project + subprocess.call(GCPHandler.get_set_project_command(project_id), shell=True) + LOGGER.info("GCP Handler set project") + LOGGER.info("GCP Handler initialized successfully") + except Exception as e: + LOGGER.error("GCP Handler failed to initialize: %s." % e) + + def start_machines(self, machine_list): + LOGGER.info("Setting up all GCP machines...") + try: + subprocess.call((GCPHandler.MACHINE_STARTING_COMMAND % (machine_list, self.zone)), shell=True) + LOGGER.info("GCP machines successfully started.") + except Exception as e: + LOGGER.error("GCP Handler failed to start GCP machines: %s" % e) + + def stop_machines(self, machine_list): + try: + subprocess.call((GCPHandler.MACHINE_STOPPING_COMMAND % (machine_list, self.zone)), shell=True) + LOGGER.info("GCP machines stopped successfully.") + except Exception as e: + LOGGER.error("GCP Handler failed to stop network machines: %s" % e) + + @staticmethod + def get_auth_command(key_path): + return GCPHandler.AUTHENTICATION_COMMAND % key_path + + @staticmethod + def get_set_project_command(project): + return GCPHandler.SET_PROPERTY_PROJECT % project diff --git a/envs/monkey_zoo/blackbox/utils/json_encoder.py b/envs/monkey_zoo/blackbox/utils/json_encoder.py new file mode 100644 index 000000000..77be9211a --- /dev/null +++ b/envs/monkey_zoo/blackbox/utils/json_encoder.py @@ -0,0 +1,9 @@ +import json +from bson import ObjectId + + +class MongoQueryJSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, ObjectId): + return str(o) + return json.JSONEncoder.default(self, o) diff --git a/envs/monkey_zoo/blackbox/utils/test_timer.py b/envs/monkey_zoo/blackbox/utils/test_timer.py new file mode 100644 index 000000000..2c0ca490a --- /dev/null +++ b/envs/monkey_zoo/blackbox/utils/test_timer.py @@ -0,0 +1,17 @@ +from time import time + + +class TestTimer(object): + def __init__(self, timeout): + self.timeout_time = TestTimer.get_timeout_time(timeout) + self.start_time = time() + + def is_timed_out(self): + return time() > self.timeout_time + + def get_time_taken(self): + return time() - self.start_time + + @staticmethod + def get_timeout_time(timeout): + return time() + timeout diff --git a/envs/monkey_zoo/gcp_keys/.gitignore b/envs/monkey_zoo/gcp_keys/.gitignore new file mode 100644 index 000000000..5e7d2734c --- /dev/null +++ b/envs/monkey_zoo/gcp_keys/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/monkey/infection_monkey/build_windows.bat b/monkey/infection_monkey/build_windows.bat index e5ff5a805..fb12f2c0e 100644 --- a/monkey/infection_monkey/build_windows.bat +++ b/monkey/infection_monkey/build_windows.bat @@ -1 +1 @@ -pyinstaller -F --log-level=DEBUG --clean --upx-dir=.\bin monkey.spec \ No newline at end of file +C:\Programos\Python27\Scripts\pyinstaller.exe -F --log-level=DEBUG --clean --upx-dir=.\bin monkey.spec \ No newline at end of file diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index dd3e9ca63..3e333a26d 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -38,4 +38,4 @@ HADOOP_LINUX_COMMAND = "! [ -f %(monkey_path)s ] " \ "; chmod +x %(monkey_path)s " \ "&& %(monkey_path)s %(monkey_type)s %(parameters)s" -DOWNLOAD_TIMEOUT = 300 +DOWNLOAD_TIMEOUT = 180 diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 35e932cb1..03d30a229 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -36,6 +36,9 @@ from monkey_island.cc.resources.pba_file_upload import FileUpload from monkey_island.cc.resources.attack.attack_config import AttackConfiguration from monkey_island.cc.resources.attack.attack_report import AttackReport +from monkey_island.cc.resources.test.monkey_test import MonkeyTest +from monkey_island.cc.resources.test.log_test import LogTest + __author__ = 'Barak' @@ -141,6 +144,9 @@ def init_api_resources(api): api.add_resource(AttackReport, '/api/attack/report') api.add_resource(VersionUpdate, '/api/version-update', '/api/version-update/') + api.add_resource(MonkeyTest, '/api/test/monkey') + api.add_resource(LogTest, '/api/test/log') + def init_app(mongo_url): app = Flask(__name__) diff --git a/monkey/monkey_island/cc/resources/test/__init__.py b/monkey/monkey_island/cc/resources/test/__init__.py new file mode 100644 index 000000000..28550f830 --- /dev/null +++ b/monkey/monkey_island/cc/resources/test/__init__.py @@ -0,0 +1,4 @@ +""" +This package contains resources used by blackbox tests +to analize test results, download logs and so on. +""" diff --git a/monkey/monkey_island/cc/resources/test/log_test.py b/monkey/monkey_island/cc/resources/test/log_test.py new file mode 100644 index 000000000..e592e7214 --- /dev/null +++ b/monkey/monkey_island/cc/resources/test/log_test.py @@ -0,0 +1,18 @@ +from bson import json_util +import flask_restful +from flask import request + + +from monkey_island.cc.auth import jwt_required +from monkey_island.cc.database import mongo, database + + +class LogTest(flask_restful.Resource): + @jwt_required() + def get(self): + find_query = json_util.loads(request.args.get('find_query')) + log = mongo.db.log.find_one(find_query) + if not log: + return {'results': None} + log_file = database.gridfs.get(log['file_id']) + return {'results': log_file.read()} diff --git a/monkey/monkey_island/cc/resources/test/monkey_test.py b/monkey/monkey_island/cc/resources/test/monkey_test.py new file mode 100644 index 000000000..100624780 --- /dev/null +++ b/monkey/monkey_island/cc/resources/test/monkey_test.py @@ -0,0 +1,13 @@ +from bson import json_util +import flask_restful +from flask import request + +from monkey_island.cc.auth import jwt_required +from monkey_island.cc.database import mongo + + +class MonkeyTest(flask_restful.Resource): + @jwt_required() + def get(self, **kw): + find_query = json_util.loads(request.args.get('find_query')) + return {'results': list(mongo.db.monkey.find(find_query))}