Merge branch 'vulture' into develop

This commit is contained in:
Mike Salvatore 2021-05-07 08:12:54 -04:00
commit aa959c3879
50 changed files with 214 additions and 437 deletions

View File

@ -1,7 +1,7 @@
[flake8] [flake8]
## Warn about linter issues. ## Warn about linter issues.
exclude = monkey/monkey_island/cc/ui exclude = monkey/monkey_island/cc/ui,whitelist.py
show-source = True show-source = True
max-complexity = 10 max-complexity = 10
max-line-length = 100 max-line-length = 100
@ -15,4 +15,3 @@ statistics = True
### --count will print the total number of errors. ### --count will print the total number of errors.
count = True count = True

View File

@ -48,3 +48,7 @@ repos:
rev: v0.2 rev: v0.2
hooks: hooks:
- id: swimm-verify - id: swimm-verify
- repo: https://github.com/jendrikseipp/vulture
rev: v2.3
hooks:
- id: vulture

View File

@ -63,6 +63,9 @@ script:
## Check that all python is properly formatted. Fail otherwise. ## Check that all python is properly formatted. Fail otherwise.
- python -m black --check . - python -m black --check .
## Check that there is no dead python code
- python -m vulture .
## Run unit tests and generate coverage data ## Run unit tests and generate coverage data
- cd monkey # This is our source dir - cd monkey # This is our source dir
- python -m pytest --cov=. # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path. - python -m pytest --cov=. # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path.

View File

@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Zerologon exploiter writes runtime artifacts to a secure temporary directory - Zerologon exploiter writes runtime artifacts to a secure temporary directory
instead of $HOME. #1143 instead of $HOME. #1143
- Authentication mechanism to use bcrypt on server side. #1139 - Authentication mechanism to use bcrypt on server side. #1139
- Removed relevant dead code as reported by Vulture. #1149
### Fixed ### Fixed
- Attempted to delete a directory when monkey config reset was called. #1054 - Attempted to delete a directory when monkey config reset was called. #1054

View File

@ -2,7 +2,6 @@ import logging
import boto3 import boto3
import botocore import botocore
from botocore.exceptions import ClientError
from common.cloud.aws.aws_instance import AwsInstance from common.cloud.aws.aws_instance import AwsInstance
@ -53,22 +52,6 @@ class AwsService(object):
client_type, region_name=region if region is not None else AwsService.region client_type, region_name=region if region is not None else AwsService.region
) )
@staticmethod
def get_session():
return boto3.session.Session()
@staticmethod
def get_regions():
return AwsService.get_session().get_available_regions("ssm")
@staticmethod
def test_client():
try:
AwsService.get_client("ssm").describe_instance_information()
return True
except ClientError:
return False
@staticmethod @staticmethod
def get_instances(): def get_instances():
""" """

View File

@ -2,7 +2,6 @@ import logging
import time import time
from abc import abstractmethod from abc import abstractmethod
from common.cmd.cmd import Cmd
from common.cmd.cmd_result import CmdResult from common.cmd.cmd_result import CmdResult
from common.cmd.cmd_status import CmdStatus from common.cmd.cmd_status import CmdStatus
@ -36,16 +35,6 @@ class CmdRunner(object):
def __init__(self, is_linux): def __init__(self, is_linux):
self.is_linux = is_linux self.is_linux = is_linux
def run_command(self, command_line, timeout=DEFAULT_TIMEOUT):
"""
Runs the given command on the remote machine
:param command_line: The command line to run
:param timeout: Timeout in seconds for command.
:return: Command result
"""
c_id = self.run_command_async(command_line)
return self.wait_commands([Cmd(self, c_id)], timeout)[1]
@staticmethod @staticmethod
def run_multiple_commands(instances, inst_to_cmd, inst_n_cmd_res_to_res): def run_multiple_commands(instances, inst_to_cmd, inst_n_cmd_res_to_res):
""" """

View File

@ -4,4 +4,3 @@ ENVIRONMENT_COLLECTOR = "EnvironmentCollector"
PROCESS_LIST_COLLECTOR = "ProcessListCollector" PROCESS_LIST_COLLECTOR = "ProcessListCollector"
MIMIKATZ_COLLECTOR = "MimikatzCollector" MIMIKATZ_COLLECTOR = "MimikatzCollector"
AZURE_CRED_COLLECTOR = "AzureCollector" AZURE_CRED_COLLECTOR = "AzureCollector"
SCOUTSUITE_COLLECTOR = "ScoutSuiteCollector"

View File

@ -42,13 +42,3 @@ class UsageEnum(Enum):
# Dict that describes what BITS job was used for # Dict that describes what BITS job was used for
BITS_UPLOAD_STRING = "BITS job was used to upload monkey to a remote system." BITS_UPLOAD_STRING = "BITS job was used to upload monkey to a remote system."
def format_time(time):
return "%s-%s %s:%s:%s" % (
time.date().month,
time.date().day,
time.time().hour,
time.time().minute,
time.time().second,
)

View File

@ -3,5 +3,4 @@ from enum import Enum
class ExploitType(Enum): class ExploitType(Enum):
VULNERABILITY = 1 VULNERABILITY = 1
OTHER = 8
BRUTE_FORCE = 9 BRUTE_FORCE = 9

View File

@ -188,7 +188,6 @@ class Configuration(object):
# exploiters config # exploiters config
########################### ###########################
should_exploit = True
skip_exploit_if_file_exist = False skip_exploit_if_file_exist = False
ms08_067_exploit_attempts = 5 ms08_067_exploit_attempts = 5

View File

@ -1,5 +1,4 @@
{ {
"should_exploit": true,
"command_servers": [ "command_servers": [
"192.0.2.0:5000" "192.0.2.0:5000"
], ],

View File

@ -73,10 +73,6 @@ class SambaCryExploiter(HostExploiter):
SAMBACRY_MONKEY_FILENAME_32 = "monkey32" SAMBACRY_MONKEY_FILENAME_32 = "monkey32"
# Monkey filename on share (64 bit) # Monkey filename on share (64 bit)
SAMBACRY_MONKEY_FILENAME_64 = "monkey64" SAMBACRY_MONKEY_FILENAME_64 = "monkey64"
# Monkey copy filename on share (32 bit)
SAMBACRY_MONKEY_COPY_FILENAME_32 = "monkey32_2"
# Monkey copy filename on share (64 bit)
SAMBACRY_MONKEY_COPY_FILENAME_64 = "monkey64_2"
# Supported samba port # Supported samba port
SAMBA_PORT = 445 SAMBA_PORT = 445
@ -465,7 +461,6 @@ class SambaCryExploiter(HostExploiter):
creationDisposition, creationDisposition,
fileAttributes, fileAttributes,
impersonationLevel=SMB2_IL_IMPERSONATION, impersonationLevel=SMB2_IL_IMPERSONATION,
securityFlags=0,
oplockLevel=SMB2_OPLOCK_LEVEL_NONE, oplockLevel=SMB2_OPLOCK_LEVEL_NONE,
createContexts=None, createContexts=None,
): ):

View File

@ -10,10 +10,6 @@ __author__ = "itamar"
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class DceRpcException(Exception):
pass
class AccessDeniedException(Exception): class AccessDeniedException(Exception):
def __init__(self, host, username, password, domain): def __init__(self, host, username, password, domain):
super(AccessDeniedException, self).__init__( super(AccessDeniedException, self).__init__(

View File

@ -25,7 +25,7 @@ from infection_monkey.model import (
RUN_MONKEY, RUN_MONKEY,
WGET_HTTP_UPLOAD, WGET_HTTP_UPLOAD,
) )
from infection_monkey.network.tools import check_tcp_port, tcp_port_to_service from infection_monkey.network.tools import tcp_port_to_service
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
@ -188,13 +188,6 @@ class WebRCE(HostExploiter):
return valid_ports return valid_ports
def check_if_port_open(self, port):
is_open, _ = check_tcp_port(self.host.ip_addr, port)
if not is_open:
LOG.info("Port %d is closed on %r, skipping", port, self.host)
return False
return True
def get_command(self, path, http_path, commands): def get_command(self, path, http_path, commands):
try: try:
if "linux" in self.host.os["type"]: if "linux" in self.host.os["type"]:
@ -578,9 +571,6 @@ class WebRCE(HostExploiter):
LOG.debug("Target's machine type was not set. Using win-32 dropper path.") LOG.debug("Target's machine type was not set. Using win-32 dropper path.")
return self._config.dropper_target_path_win_32 return self._config.dropper_target_path_win_32
def set_vulnerable_port_from_url(self, url):
self.vulnerable_port = HTTPTools.get_port_from_url(url)
def get_target_url(self): def get_target_url(self):
""" """
This method allows "configuring" the way in which a vulnerable URL is picked. This method allows "configuring" the way in which a vulnerable URL is picked.

View File

@ -17,7 +17,6 @@ MONKEY_CMDLINE_WINDOWS = "%s %%(monkey_path)s %s" % (
MONKEY_ARG, MONKEY_ARG,
) )
MONKEY_CMDLINE_LINUX = "./%%(monkey_filename)s %s" % (MONKEY_ARG,) MONKEY_CMDLINE_LINUX = "./%%(monkey_filename)s %s" % (MONKEY_ARG,)
GENERAL_CMDLINE_LINUX = "(cd %(monkey_directory)s && %(monkey_commandline)s)"
DROPPER_CMDLINE_DETACHED_WINDOWS = "%s start cmd /c %%(dropper_path)s %s" % ( DROPPER_CMDLINE_DETACHED_WINDOWS = "%s start cmd /c %%(dropper_path)s %s" % (
CMD_PREFIX, CMD_PREFIX,
DROPPER_ARG, DROPPER_ARG,
@ -26,14 +25,6 @@ MONKEY_CMDLINE_DETACHED_WINDOWS = "%s start cmd /c %%(monkey_path)s %s" % (
CMD_PREFIX, CMD_PREFIX,
MONKEY_ARG, MONKEY_ARG,
) )
MONKEY_CMDLINE_HTTP = (
'%s /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s'
'&cmd /c %%(monkey_path)s %s"'
% (
CMD_PREFIX,
MONKEY_ARG,
)
)
DELAY_DELETE_CMD = ( DELAY_DELETE_CMD = (
"cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & " "cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & "
"if not exist %(file_path)s exit)) > NUL 2>&1 " "if not exist %(file_path)s exit)) > NUL 2>&1 "

View File

@ -56,12 +56,10 @@ class InfectionMonkey(object):
self._default_tunnel = None self._default_tunnel = None
self._args = args self._args = args
self._network = None self._network = None
self._dropper_path = None
self._exploiters = None self._exploiters = None
self._fingerprint = None self._fingerprint = None
self._default_server = None self._default_server = None
self._default_server_port = None self._default_server_port = None
self._depth = 0
self._opts = None self._opts = None
self._upgrading_to_64 = False self._upgrading_to_64 = False
@ -92,7 +90,6 @@ class InfectionMonkey(object):
self._keep_running = True self._keep_running = True
self._network = NetworkScanner() self._network = NetworkScanner()
self._dropper_path = sys.argv[0]
if self._default_server: if self._default_server:
if self._default_server not in WormConfiguration.command_servers: if self._default_server not in WormConfiguration.command_servers:

View File

@ -15,7 +15,6 @@ class VirtualFile(BytesIO):
if not name.startswith(MONKEYFS_PREFIX): if not name.startswith(MONKEYFS_PREFIX):
name = MONKEYFS_PREFIX + name name = MONKEYFS_PREFIX + name
self.name = name self.name = name
self._mode = mode
if name in VirtualFile._vfs: if name in VirtualFile._vfs:
super(VirtualFile, self).__init__(self._vfs[name]) super(VirtualFile, self).__init__(self._vfs[name])
else: else:

View File

@ -31,7 +31,7 @@ class FirewallApp(object):
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, exc_type, value, traceback): def __exit__(self, _exc_type, value, traceback):
self.close() self.close()
def close(self): def close(self):

View File

@ -2,7 +2,6 @@ import itertools
import socket import socket
import struct import struct
from random import randint # noqa: DUO102 from random import randint # noqa: DUO102
from subprocess import check_output
import netifaces import netifaces
import psutil import psutil
@ -157,22 +156,3 @@ def get_interfaces_ranges():
# limit subnet scans to class C only # limit subnet scans to class C only
res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str))) res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str)))
return res return res
if is_windows_os():
def get_ip_for_connection(target_ip):
return None
else:
def get_ip_for_connection(target_ip):
try:
query_str = "ip route get %s" % target_ip
resp = check_output(query_str.split())
substr = resp.split()
src = substr[substr.index("src") + 1]
return src
except Exception:
return None

View File

@ -1,22 +1,16 @@
import logging import logging
import re
import select import select
import socket import socket
import struct import struct
import subprocess
import sys import sys
import time import time
from common.network.network_utils import get_host_from_network_location from common.network.network_utils import get_host_from_network_location
from infection_monkey.config import WormConfiguration from infection_monkey.config import WormConfiguration
from infection_monkey.network.info import get_routes, local_ips from infection_monkey.network.info import get_routes, local_ips
from infection_monkey.pyinstaller_utils import get_binary_file_path
from infection_monkey.utils.environment import is_64bit_python
DEFAULT_TIMEOUT = 10 DEFAULT_TIMEOUT = 10
BANNER_READ = 1024 BANNER_READ = 1024
IP_ADDR_RE = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
IP_ADDR_PARENTHESES_RE = r"\(" + IP_ADDR_RE + r"\)"
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
SLEEP_BETWEEN_POLL = 0.5 SLEEP_BETWEEN_POLL = 0.5
@ -82,31 +76,6 @@ def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
return True, banner return True, banner
def check_udp_port(ip, port, timeout=DEFAULT_TIMEOUT):
"""
Checks if a given UDP port is open by checking if it replies to an empty message
:param ip: Target IP
:param port: Target port
:param timeout: Timeout to wait
:return: Tuple, T/F + banner
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
data = None
is_open = False
try:
sock.sendto(b"-", (ip, port))
data, _ = sock.recvfrom(BANNER_READ)
is_open = True
except socket.error:
pass
sock.close()
return is_open, data
def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False): def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
""" """
Checks whether any of the given ports are open on a target IP. Checks whether any of the given ports are open on a target IP.
@ -189,97 +158,6 @@ def tcp_port_to_service(port):
return "tcp-" + str(port) return "tcp-" + str(port)
def traceroute(target_ip, ttl=64):
"""
Traceroute for a specific IP/name.
Note, may throw exception on failure that should be handled by caller.
:param target_ip: IP/name of target
:param ttl: Max TTL
:return: Sequence of IPs in the way
"""
if sys.platform == "win32":
return _traceroute_windows(target_ip, ttl)
else: # linux based hopefully
return _traceroute_linux(target_ip, ttl)
def _get_traceroute_bin_path():
"""
Gets the path to the prebuilt traceroute executable
This is the traceroute utility from: http://traceroute.sourceforge.net
Its been built using the buildroot utility with the following settings:
* Statically link to musl and all other required libs
* Optimize for size
This is done because not all linux distros come with traceroute out-of-the-box, and to ensure
it behaves as expected
:return: Path to traceroute executable
"""
return get_binary_file_path("traceroute64" if is_64bit_python() else "traceroute32")
def _parse_traceroute(output, regex, ttl):
"""
Parses the output of traceroute (from either Linux or Windows)
:param output: The output of the traceroute
:param regex: Regex for finding an IP address
:param ttl: Max TTL. Must be the same as the TTL used as param for traceroute.
:return: List of ips which are the hops on the way to the traceroute destination.
If a hop's IP wasn't found by traceroute, instead of an IP, the array will
contain None
"""
ip_lines = output.split("\n")
trace_list = []
first_line_index = None
for i in range(len(ip_lines)):
if re.search(r"^\s*1", ip_lines[i]) is not None:
first_line_index = i
break
for i in range(first_line_index, first_line_index + ttl):
if (
re.search(r"^\s*" + str(i - first_line_index + 1), ip_lines[i]) is None
): # If trace is finished
break
re_res = re.search(regex, ip_lines[i])
if re_res is None:
ip_addr = None
else:
ip_addr = re_res.group()
trace_list.append(ip_addr)
return trace_list
def _traceroute_windows(target_ip, ttl):
"""
Traceroute for a specific IP/name - Windows implementation
"""
# we'll just use tracert because that's always there
cli = ["tracert", "-d", "-w", "250", "-h", str(ttl), target_ip]
proc_obj = subprocess.Popen(cli, stdout=subprocess.PIPE)
stdout, stderr = proc_obj.communicate()
stdout = stdout.replace("\r", "")
return _parse_traceroute(stdout, IP_ADDR_RE, ttl)
def _traceroute_linux(target_ip, ttl):
"""
Traceroute for a specific IP/name - Linux implementation
"""
cli = [_get_traceroute_bin_path(), "-m", str(ttl), target_ip]
proc_obj = subprocess.Popen(cli, stdout=subprocess.PIPE)
stdout, stderr = proc_obj.communicate()
lines = _parse_traceroute(stdout, IP_ADDR_PARENTHESES_RE, ttl)
lines = [x[1:-1] if x else None for x in lines] # Removes parenthesis
return lines
def get_interface_to_target(dst): def get_interface_to_target(dst):
""" """
:param dst: destination IP address string without port. E.G. '192.168.1.1.' :param dst: destination IP address string without port. E.G. '192.168.1.1.'

View File

@ -37,14 +37,6 @@ class PBA(Plugin):
self.command = PBA.choose_command(linux_cmd, windows_cmd) self.command = PBA.choose_command(linux_cmd, windows_cmd)
self.name = name self.name = name
def get_pba(self):
"""
This method returns a PBA object based on a worm's configuration.
Return None or False if you don't want the pba to be executed.
:return: A pba object.
"""
return self
@staticmethod @staticmethod
def should_run(class_name): def should_run(class_name):
""" """

View File

@ -3,14 +3,11 @@ from multiprocessing.dummy import Pool
from typing import Sequence from typing import Sequence
from infection_monkey.post_breach.pba import PBA from infection_monkey.post_breach.pba import PBA
from infection_monkey.utils.environment import is_windows_os
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
__author__ = "VakarisZ" __author__ = "VakarisZ"
PATH_TO_ACTIONS = "infection_monkey.post_breach.actions."
class PostBreach(object): class PostBreach(object):
""" """
@ -18,7 +15,6 @@ class PostBreach(object):
""" """
def __init__(self): def __init__(self):
self.os_is_linux = not is_windows_os()
self.pba_list = self.config_to_pba_list() self.pba_list = self.config_to_pba_list()
def execute_all_configured(self): def execute_all_configured(self):

View File

@ -10,73 +10,3 @@ WMI_CLASSES = {
"Win32_Service", "Win32_Service",
"Win32_OptionalFeature", "Win32_OptionalFeature",
} }
# These wmi queries are able to return data about all the users & machines in the domain.
# For these queries to work, the monkey should be run on a domain machine and
#
# monkey should run as *** SYSTEM *** !!!
#
WMI_LDAP_CLASSES = {
"ds_user": (
"DS_sAMAccountName",
"DS_userPrincipalName",
"DS_sAMAccountType",
"ADSIPath",
"DS_userAccountControl",
"DS_objectSid",
"DS_objectClass",
"DS_memberOf",
"DS_primaryGroupID",
"DS_pwdLastSet",
"DS_badPasswordTime",
"DS_badPwdCount",
"DS_lastLogon",
"DS_lastLogonTimestamp",
"DS_lastLogoff",
"DS_logonCount",
"DS_accountExpires",
),
"ds_group": (
"DS_whenChanged",
"DS_whenCreated",
"DS_sAMAccountName",
"DS_sAMAccountType",
"DS_objectSid",
"DS_objectClass",
"DS_name",
"DS_memberOf",
"DS_member",
"DS_instanceType",
"DS_cn",
"DS_description",
"DS_distinguishedName",
"ADSIPath",
),
"ds_computer": (
"DS_dNSHostName",
"ADSIPath",
"DS_accountExpires",
"DS_adminDisplayName",
"DS_badPasswordTime",
"DS_badPwdCount",
"DS_cn",
"DS_distinguishedName",
"DS_instanceType",
"DS_lastLogoff",
"DS_lastLogon",
"DS_lastLogonTimestamp",
"DS_logonCount",
"DS_objectClass",
"DS_objectSid",
"DS_operatingSystem",
"DS_operatingSystemVersion",
"DS_primaryGroupID",
"DS_pwdLastSet",
"DS_sAMAccountName",
"DS_sAMAccountType",
"DS_servicePrincipalName",
"DS_userAccountControl",
"DS_whenChanged",
"DS_whenCreated",
),
}

View File

@ -11,11 +11,6 @@ LOG = logging.getLogger(__name__)
class _SystemSingleton(object, metaclass=ABCMeta): class _SystemSingleton(object, metaclass=ABCMeta):
@property
@abstractmethod
def locked(self):
raise NotImplementedError()
@abstractmethod @abstractmethod
def try_lock(self): def try_lock(self):
raise NotImplementedError() raise NotImplementedError()
@ -30,10 +25,6 @@ class WindowsSystemSingleton(_SystemSingleton):
self._mutex_name = r"Global\%s" % (WormConfiguration.singleton_mutex_name,) self._mutex_name = r"Global\%s" % (WormConfiguration.singleton_mutex_name,)
self._mutex_handle = None self._mutex_handle = None
@property
def locked(self):
return self._mutex_handle is not None
def try_lock(self): def try_lock(self):
assert self._mutex_handle is None, "Singleton already locked" assert self._mutex_handle is None, "Singleton already locked"
@ -67,10 +58,6 @@ class LinuxSystemSingleton(_SystemSingleton):
self._unix_sock_name = str(WormConfiguration.singleton_mutex_name) self._unix_sock_name = str(WormConfiguration.singleton_mutex_name)
self._sock_handle = None self._sock_handle = None
@property
def locked(self):
return self._sock_handle is not None
def try_lock(self): def try_lock(self):
assert self._sock_handle is None, "Singleton already locked" assert self._sock_handle is None, "Singleton already locked"

View File

@ -115,9 +115,6 @@ class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler): class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
timeout = 30 # timeout with clients, set to None not to make persistent connection timeout = 30 # timeout with clients, set to None not to make persistent connection
proxy_via = (
None # pseudonym of the proxy in Via header, set to None not to modify original Via header
)
def do_POST(self): def do_POST(self):
try: try:

View File

@ -31,7 +31,7 @@ class AutoNewUser(metaclass=abc.ABCMeta):
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, _exc_type, value, traceback):
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod

View File

@ -54,7 +54,7 @@ class AutoNewLinuxUser(AutoNewUser):
) )
return subprocess.call(command_as_new_user) return subprocess.call(command_as_new_user)
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, _exc_type, value, traceback):
# delete the user. # delete the user.
commands_to_delete_user = get_linux_commands_to_delete_user(self.username) commands_to_delete_user = get_linux_commands_to_delete_user(self.username)
logger.debug( logger.debug(

View File

@ -1,10 +1,6 @@
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import PluginTester from infection_monkey.utils.plugins.pluginTests.PluginTestClass import PluginTester
class NoInheritance:
pass
class BadInit(PluginTester): class BadInit(PluginTester):
def __init__(self): def __init__(self):
raise Exception("TestException") raise Exception("TestException")

View File

@ -108,10 +108,7 @@ class AutoNewWindowsUser(AutoNewUser):
return exit_code return exit_code
def get_logon_handle(self): def __exit__(self, _exc_type, value, traceback):
return self.logon_handle
def __exit__(self, exc_type, exc_val, exc_tb):
# Logoff # Logoff
self.logon_handle.Close() self.logon_handle.Close()

View File

@ -42,6 +42,7 @@ flake8 = "==3.9.0"
pytest-cov = "*" pytest-cov = "*"
isort = "==5.8.0" isort = "==5.8.0"
coverage = "*" coverage = "*"
vulture = "==2.3"
[requires] [requires]
python_version = "3.7" python_version = "3.7"

View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "3057235b1e85593ee307d9e5a2e0d15e26f13437bb709529303c7c900d3c7b41" "sha256": "6734e0c45321194a1ec4ac2e91af8efb9b9dd9e7f02af146d01219dc64847a51"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -1447,6 +1447,14 @@
"index": "pypi", "index": "pypi",
"version": "==20.4.3" "version": "==20.4.3"
}, },
"vulture": {
"hashes": [
"sha256:03d5a62bcbe9ceb9a9b0575f42d71a2d414070229f2e6f95fa6e7c71aaaed967",
"sha256:f39de5e6f1df1f70c3b50da54f1c8d494159e9ca3d01a9b89eac929600591703"
],
"index": "pypi",
"version": "==2.3"
},
"zipp": { "zipp": {
"hashes": [ "hashes": [
"sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76",

View File

@ -1,4 +1,3 @@
import hashlib
import logging import logging
import os import os
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
@ -106,21 +105,12 @@ class Environment(object, metaclass=ABCMeta):
def get_auth_expiration_time(self): def get_auth_expiration_time(self):
return self._AUTH_EXPIRATION_TIME return self._AUTH_EXPIRATION_TIME
@staticmethod
def hash_secret(secret):
hash_obj = hashlib.sha3_512()
hash_obj.update(secret.encode("utf-8"))
return hash_obj.hexdigest()
def get_deployment(self) -> str: def get_deployment(self) -> str:
deployment = "unknown" deployment = "unknown"
if self._config and self._config.deployment: if self._config and self._config.deployment:
deployment = self._config.deployment deployment = self._config.deployment
return deployment return deployment
def set_deployment(self, deployment: str):
self._config.deployment = deployment
@property @property
def mongo_db_name(self): def mongo_db_name(self):
return self._MONGO_DB_NAME return self._MONGO_DB_NAME

View File

@ -11,14 +11,6 @@ class AwsEnvironment(Environment):
super(AwsEnvironment, self).__init__(config) super(AwsEnvironment, self).__init__(config)
# Not suppressing error here on purpose. This is critical if we're on AWS env. # Not suppressing error here on purpose. This is critical if we're on AWS env.
self.aws_info = AwsInstance() self.aws_info = AwsInstance()
self._instance_id = self._get_instance_id()
self.region = self._get_region()
def _get_instance_id(self):
return self.aws_info.get_instance_id()
def _get_region(self):
return self.aws_info.get_region()
def get_auth_users(self): def get_auth_users(self):
if self._is_registered(): if self._is_registered():

View File

@ -20,8 +20,6 @@ from monkey_island.cc.models.monkey_ttl import MonkeyTtl, create_monkey_ttl_docu
from monkey_island.cc.server_utils.consts import DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS from monkey_island.cc.server_utils.consts import DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS
from monkey_island.cc.services.utils.network_utils import local_ip_addresses from monkey_island.cc.services.utils.network_utils import local_ip_addresses
MAX_MONKEYS_AMOUNT_TO_CACHE = 100
class Monkey(Document): class Monkey(Document):
""" """

View File

@ -6,10 +6,8 @@ from monkey_island.cc.resources.auth.auth_user import User
class UserStore: class UserStore:
users = [] users = []
username_table = {} username_table = {}
user_id_table = {}
@staticmethod @staticmethod
def set_users(users: List[User]): def set_users(users: List[User]):
UserStore.users = users UserStore.users = users
UserStore.username_table = {u.username: u for u in UserStore.users} UserStore.username_table = {u.username: u for u in UserStore.users}
UserStore.user_id_table = {u.id: u for u in UserStore.users}

View File

@ -1,5 +1,4 @@
import logging import logging
import threading
import flask_restful import flask_restful
from flask import jsonify, make_response, request from flask import jsonify, make_response, request
@ -16,9 +15,6 @@ logger = logging.getLogger(__name__)
class Root(flask_restful.Resource): class Root(flask_restful.Resource):
def __init__(self):
self.report_generating_lock = threading.Event()
def get(self, action=None): def get(self, action=None):
if not action: if not action:
action = request.args.get("action") action = request.args.get("action")

View File

@ -3,7 +3,6 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn from socketserver import ThreadingMixIn
from urllib import parse from urllib import parse
import pymongo
import requests import requests
import urllib3 import urllib3
@ -17,7 +16,6 @@ logger = logging.getLogger(__name__)
class BootloaderHttpServer(ThreadingMixIn, HTTPServer): class BootloaderHttpServer(ThreadingMixIn, HTTPServer):
def __init__(self, mongo_url): def __init__(self, mongo_url):
self.mongo_client = pymongo.MongoClient(mongo_url)
server_address = ("", 5001) server_address = ("", 5001)
super().__init__(server_address, BootloaderHTTPRequestHandler) super().__init__(server_address, BootloaderHTTPRequestHandler)

View File

@ -119,19 +119,6 @@ class AttackReportService:
mongo.db.attack_report.replace_one({"name": REPORT_NAME}, report, upsert=True) mongo.db.attack_report.replace_one({"name": REPORT_NAME}, report, upsert=True)
return report return report
@staticmethod
def get_latest_attack_telem_time():
"""
Gets timestamp of latest attack telem
:return: timestamp of latest attack telem
"""
return [
x["timestamp"]
for x in mongo.db.telemetry.find({"telem_category": "attack"})
.sort("timestamp", -1)
.limit(1)
][0]
@staticmethod @staticmethod
def get_latest_report(): def get_latest_report():
""" """

View File

@ -104,17 +104,6 @@ class NodeService:
return True return True
@staticmethod
def get_monkey_label_by_id(monkey_id):
return NodeService.get_monkey_label(NodeService.get_monkey_by_id(monkey_id))
@staticmethod
def get_monkey_critical_services(monkey_id):
critical_services = mongo.db.monkey.find_one(
{"_id": monkey_id}, {"critical_services": 1}
).get("critical_services", [])
return critical_services
@staticmethod @staticmethod
def get_monkey_label(monkey): def get_monkey_label(monkey):
# todo # todo

View File

@ -12,7 +12,6 @@ logger = logging.getLogger(__name__)
# Where to find file names in config # Where to find file names in config
PBA_WINDOWS_FILENAME_PATH = ["monkey", "post_breach", "PBA_windows_filename"] PBA_WINDOWS_FILENAME_PATH = ["monkey", "post_breach", "PBA_windows_filename"]
PBA_LINUX_FILENAME_PATH = ["monkey", "post_breach", "PBA_linux_filename"] PBA_LINUX_FILENAME_PATH = ["monkey", "post_breach", "PBA_linux_filename"]
UPLOADS_DIR_NAME = "userUploads"
def remove_PBA_files(): def remove_PBA_files():

View File

@ -13,7 +13,6 @@ logger = logging.getLogger(__name__)
class RemoteRunAwsService: class RemoteRunAwsService:
aws_instance = None aws_instance = None
is_auth = False
def __init__(self): def __init__(self):
pass pass

View File

@ -763,12 +763,3 @@ class ReportService:
if ReportService.is_latest_report_exists(): if ReportService.is_latest_report_exists():
return ReportService.decode_dot_char_before_mongo_insert(mongo.db.report.find_one()) return ReportService.decode_dot_char_before_mongo_insert(mongo.db.report.find_one())
return safe_generate_regular_report() return safe_generate_regular_report()
@staticmethod
def did_exploit_type_succeed(exploit_type):
return (
mongo.db.edge.count(
{"exploits": {"$elemMatch": {"exploiter": exploit_type, "result": True}}}, limit=1
)
> 0
)

View File

@ -26,8 +26,6 @@ EVENTS_DTO = [
for event in EVENTS for event in EVENTS
] ]
DETAILS_DTO = []
def get_monkey_details_dto() -> MonkeyFindingDetails: def get_monkey_details_dto() -> MonkeyFindingDetails:
monkey_details = MonkeyFindingDetails() monkey_details = MonkeyFindingDetails()

View File

@ -1,26 +0,0 @@
"""
Utility script for running a string through SHA3_512 hash.
Used for Monkey Island password hash, see
https://github.com/guardicore/monkey/wiki/Enabling-Monkey-Island-Password-Protection
for more details.
"""
import argparse
# PyCrypto is deprecated, but we use pycryptodome, which uses the exact same imports but
# is maintained.
from Crypto.Hash import SHA3_512 # noqa: DUO133 # nosec: B413
def main():
parser = argparse.ArgumentParser()
parser.add_argument("string_to_sha", help="The string to do sha for")
args = parser.parse_args()
h = SHA3_512.new()
h.update(args.string_to_sha)
print(h.hexdigest())
if __name__ == "__main__":
main()

View File

@ -63,10 +63,6 @@ class StubEnvironmentConfig(EnvironmentConfig):
os.remove(self.server_config_path) os.remove(self.server_config_path)
def get_server_config_file_path_test_version():
return os.path.join(os.getcwd(), "test_config.json")
class TestEnvironment(TestCase): class TestEnvironment(TestCase):
class EnvironmentCredentialsNotRequired(Environment): class EnvironmentCredentialsNotRequired(Environment):
def __init__(self): def __init__(self):

View File

@ -2,7 +2,6 @@ from monkey_island.cc.environment.user_creds import UserCreds
TEST_USER = "Test" TEST_USER = "Test"
TEST_HASH = "abc1231234" TEST_HASH = "abc1231234"
TEST_SALT = b"$2b$12$JA7GdT1iyfIsquF2cTZv2."
def test_bool_true(): def test_bool_true():

View File

@ -21,7 +21,6 @@ NT_HASH = "a9fdfa038c4b75ebc76dc855dd74f0da"
VICTIM_IP = "0.0.0.0" VICTIM_IP = "0.0.0.0"
VICTIM_DOMAIN_NAME = "domain-name" VICTIM_DOMAIN_NAME = "domain-name"
HOSTNAME = "name-of-host" HOSTNAME = "name-of-host"
EXPLOITER_CLASS_NAME = "exploiter-name"
# Below telem constants only contain fields relevant to current tests # Below telem constants only contain fields relevant to current tests

View File

@ -2,17 +2,6 @@ from unittest import TestCase
from monkey_island.cc.services.bootloader import BootloaderService from monkey_island.cc.services.bootloader import BootloaderService
WINDOWS_VERSIONS = {
"5.0": "Windows 2000",
"5.1": "Windows XP",
"5.2": "Windows XP/server 2003",
"6.0": "Windows Vista/server 2008",
"6.1": "Windows 7/server 2008R2",
"6.2": "Windows 8/server 2012",
"6.3": "Windows 8.1/server 2012R2",
"10.0": "Windows 10/server 2016-2019",
}
MIN_GLIBC_VERSION = 2.14 MIN_GLIBC_VERSION = 2.14

View File

@ -21,3 +21,7 @@ log_cli_format = "%(asctime)s [%(levelname)s] %(module)s.%(funcName)s.%(lineno)d
log_cli_date_format = "%H:%M:%S" log_cli_date_format = "%H:%M:%S"
addopts = "-v --capture=sys tests" addopts = "-v --capture=sys tests"
norecursedirs = "node_modules dist" norecursedirs = "node_modules dist"
[tool.vulture]
exclude = ["monkey/monkey_island/cc/ui"]
paths = ["."]

186
whitelist.py Normal file
View File

@ -0,0 +1,186 @@
"""
Everything in this file is what Vulture found as dead code but either isn't really
dead or is kept deliberately. Referencing these in a file like this makes sure that
Vulture doesn't mark these as dead again.
"""
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37)
set_os_linux # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37)
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:57)
set_os_windows # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:57)
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:77)
set_os_linux # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:77)
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:92)
set_os_windows # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:92)
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:107)
set_os_linux # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:107)
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:122)
set_os_windows # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:122)
patch_new_user_classes # unused variable (monkey/tests/infection_monkey/utils/test_auto_new_user_factory.py:25)
patch_new_user_classes # unused variable (monkey/tests/infection_monkey/utils/test_auto_new_user_factory.py:31)
mock_home_env # unused variable (monkey/tests/monkey_island/cc/server_utils/test_island_logger.py:20)
configure_resources # unused function (monkey/tests/monkey_island/cc/environment/test_environment.py:26)
change_to_mongo_mock # unused function (monkey/monkey_island/cc/test_common/fixtures/mongomock_fixtures.py:9)
uses_database # unused function (monkey/monkey_island/cc/test_common/fixtures/mongomock_fixtures.py:16)
datas # unused variable (monkey/monkey_island/pyinstaller_hooks/hook-stix2.py:9)
test_key # unused variable (monkey/monkey_island/cc/services/zero_trust/zero_trust_report/finding_service.py:20)
pillars # unused variable (monkey/monkey_island/cc/services/zero_trust/zero_trust_report/finding_service.py:21)
CLEAN_UNKNOWN # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:9)
CLEAN_LINUX # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:10)
CLEAN_WINDOWS # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:11)
EXPLOITED_LINUX # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:12)
EXPLOITED_WINDOWS # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:13)
ISLAND_MONKEY_LINUX # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:15)
ISLAND_MONKEY_LINUX_RUNNING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:16)
ISLAND_MONKEY_LINUX_STARTING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:17)
ISLAND_MONKEY_WINDOWS # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:18)
ISLAND_MONKEY_WINDOWS_RUNNING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:19)
ISLAND_MONKEY_WINDOWS_STARTING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:20)
MANUAL_LINUX # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:21)
MANUAL_LINUX_RUNNING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:22)
MANUAL_WINDOWS # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:23)
MANUAL_WINDOWS_RUNNING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:24)
MONKEY_LINUX # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:25)
MONKEY_WINDOWS # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:27)
MONKEY_WINDOWS_RUNNING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:28)
MONKEY_WINDOWS_STARTING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:29)
MONKEY_LINUX_STARTING # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:30)
MONKEY_WINDOWS_OLD # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:31)
MONKEY_LINUX_OLD # unused variable (monkey/monkey_island/cc/services/utils/node_states.py:32)
_.credential_type # unused attribute (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py:19)
_.credential_type # unused attribute (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py:22)
_.credential_type # unused attribute (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py:25)
_.password_restored # unused attribute (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/zerologon.py:11)
credential_type # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py:18)
password_restored # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py:23)
SSH # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:30)
SAMBACRY # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:31)
ELASTIC # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:32)
MS08_067 # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:35)
SHELLSHOCK # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:36)
STRUTS2 # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:39)
WEBLOGIC # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:40)
HADOOP # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:43)
MSSQL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:44)
VSFTPD # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:45)
DRUPAL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:48)
_.do_POST # unused method (monkey/monkey_island/cc/server_utils/bootloader_server.py:26)
PbaResults # unused class (monkey/monkey_island/cc/models/pba_results.py:4)
internet_access # unused variable (monkey/monkey_island/cc/models/monkey.py:43)
config_error # unused variable (monkey/monkey_island/cc/models/monkey.py:53)
pba_results # unused variable (monkey/monkey_island/cc/models/monkey.py:55)
command_control_channel # unused variable (monkey/monkey_island/cc/models/monkey.py:58)
meta # unused variable (monkey/monkey_island/cc/models/zero_trust/finding.py:37)
meta # unused variable (monkey/monkey_island/cc/models/monkey_ttl.py:34)
expire_at # unused variable (monkey/monkey_island/cc/models/monkey_ttl.py:36)
meta # unused variable (monkey/monkey_island/cc/models/config.py:11)
meta # unused variable (monkey/monkey_island/cc/models/creds.py:9)
meta # unused variable (monkey/monkey_island/cc/models/edge.py:5)
Config # unused class (monkey/monkey_island/cc/models/config.py:4)
Creds # unused class (monkey/monkey_island/cc/models/creds.py:4)
_.do_CONNECT # unused method (monkey/infection_monkey/transport/http.py:151)
_.do_POST # unused method (monkey/infection_monkey/transport/http.py:122)
_.do_HEAD # unused method (monkey/infection_monkey/transport/http.py:61)
_.do_GET # unused method (monkey/infection_monkey/transport/http.py:38)
_.do_POST # unused method (monkey/infection_monkey/transport/http.py:34)
_.do_GET # unused method (monkey/infection_monkey/exploit/weblogic.py:237)
ElasticFinger # unused class (monkey/infection_monkey/network/elasticfinger.py:18)
HTTPFinger # unused class (monkey/infection_monkey/network/httpfinger.py:9)
MySQLFinger # unused class (monkey/infection_monkey/network/mysqlfinger.py:13)
SSHFinger # unused class (monkey/infection_monkey/network/sshfinger.py:15)
ClearCommandHistory # unused class (monkey/infection_monkey/post_breach/actions/clear_command_history.py:11)
AccountDiscovery # unused class (monkey/infection_monkey/post_breach/actions/discover_accounts.py:8)
ModifyShellStartupFiles # unused class (monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py:11)
Timestomping # unused class (monkey/infection_monkey/post_breach/actions/timestomping.py:6)
SignedScriptProxyExecution # unused class (monkey/infection_monkey/post_breach/actions/use_signed_scripts.py:15)
AwsCollector # unused class (monkey/infection_monkey/system_info/collectors/aws_collector.py:15)
EnvironmentCollector # unused class (monkey/infection_monkey/system_info/collectors/environment_collector.py:19)
HostnameCollector # unused class (monkey/infection_monkey/system_info/collectors/hostname_collector.py:10)
ProcessListCollector # unused class (monkey/infection_monkey/system_info/collectors/process_list_collector.py:18)
_.coinit_flags # unused attribute (monkey/infection_monkey/system_info/windows_info_collector.py:11)
_.representations # unused attribute (monkey/monkey_island/cc/app.py:180)
_.log_message # unused method (monkey/infection_monkey/transport/http.py:188)
_.log_message # unused method (monkey/infection_monkey/transport/http.py:109)
_.version_string # unused method (monkey/infection_monkey/transport/http.py:148)
_.version_string # unused method (monkey/infection_monkey/transport/http.py:27)
_.close_connection # unused attribute (monkey/infection_monkey/transport/http.py:57)
protocol_version # unused variable (monkey/infection_monkey/transport/http.py:24)
hiddenimports # unused variable (monkey/infection_monkey/pyinstaller_hooks/hook-infection_monkey.exploit.py:3)
hiddenimports # unused variable (monkey/infection_monkey/pyinstaller_hooks/hook-infection_monkey.network.py:3)
hiddenimports # unused variable (monkey/infection_monkey/pyinstaller_hooks/hook-infection_monkey.post_breach.actions.py:4)
hiddenimports # unused variable (monkey/infection_monkey/pyinstaller_hooks/hook-infection_monkey.system_info.collectors.py:4)
_.wShowWindow # unused attribute (monkey/infection_monkey/monkey.py:345)
_.dwFlags # unused attribute (monkey/infection_monkey/monkey.py:344)
_.do_get # unused method (monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py:79)
_.do_exit # unused method (monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py:96)
_.prompt # unused attribute (monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py:108)
_.prompt # unused attribute (monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py:125)
keytab # unused variable (monkey/infection_monkey/exploit/zerologon_utils/options.py:16)
no_pass # unused variable (monkey/infection_monkey/exploit/zerologon_utils/options.py:18)
ts # unused variable (monkey/infection_monkey/exploit/zerologon_utils/options.py:25)
opnum # unused variable (monkey/infection_monkey/exploit/zerologon.py:466)
structure # unused variable (monkey/infection_monkey/exploit/zerologon.py:467)
structure # unused variable (monkey/infection_monkey/exploit/zerologon.py:478)
_._port # unused attribute (monkey/infection_monkey/exploit/win_ms08_067.py:123)
oid_set # unused variable (monkey/infection_monkey/exploit/tools/wmi_tools.py:96)
export_monkey_telems # unused variable (monkey/infection_monkey/config.py:282)
NoInternetError # unused class (monkey/common/utils/exceptions.py:33)
_.__isabstractmethod__ # unused attribute (monkey/common/utils/code_utils.py:11)
MIMIKATZ # unused variable (monkey/common/utils/attack_utils.py:21)
MIMIKATZ_WINAPI # unused variable (monkey/common/utils/attack_utils.py:25)
DROPPER # unused variable (monkey/common/utils/attack_utils.py:29)
pytest_addoption # unused function (envs/os_compatibility/conftest.py:4)
pytest_addoption # unused function (envs/monkey_zoo/blackbox/conftest.py:4)
pytest_runtest_setup # unused function (envs/monkey_zoo/blackbox/conftest.py:47)
config_value_list # unused variable (envs/monkey_zoo/blackbox/config_templates/smb_pth.py:10)
_.dashboard_name # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:13)
_.checked_items # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:14)
_.flagged_items # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:15)
_.rationale # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:17)
_.remediation # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:18)
_.compliance # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:19)
_.references # unused attribute (monkey/monkey_island/cc/services/zero_trust/scoutsuite/scoutsuite_rule_service.py:20)
ACM # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:8)
AWSLAMBDA # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:9)
DIRECTCONNECT # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:14)
EFS # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:16)
ELASTICACHE # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:17)
EMR # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:20)
KMS # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:22)
ROUTE53 # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:25)
SECRETSMANAGER # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/service_consts.py:31)
RDS_SNAPSHOT_PUBLIC # unused variable (monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/rds_rules.py:17)
dashboard_name # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:18)
checked_items # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:19)
flagged_items # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:20)
rationale # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:22)
remediation # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:23)
compliance # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:24)
references # unused variable (monkey/monkey_island/cc/models/zero_trust/scoutsuite_rule.py:25)
ALIBABA # unused variable (monkey/common/cloud/scoutsuite_consts.py:8)
ORACLE # unused variable (monkey/common/cloud/scoutsuite_consts.py:9)
ALIBABA # unused variable (monkey/common/cloud/environment_names.py:10)
IBM # unused variable (monkey/common/cloud/environment_names.py:11)
DigitalOcean # unused variable (monkey/common/cloud/environment_names.py:12)
_.aws_info # unused attribute (monkey/monkey_island/cc/environment/aws.py:13)
# these are not needed for it to work, but may be useful extra information to understand what's going on
WINDOWS_PBA_TYPE # unused variable (monkey/monkey_island/cc/resources/pba_file_upload.py:23)
WINDOWS_TTL # unused variable (monkey/infection_monkey/network/ping_scanner.py:17)
wlist # unused variable (monkey/infection_monkey/transport/tcp.py:28)
wlist # unused variable (monkey/infection_monkey/transport/http.py:176)
charset # unused variable (monkey/infection_monkey/network/mysqlfinger.py:81)
salt # unused variable (monkey/infection_monkey/network/mysqlfinger.py:78)
thread_id # unused variable (monkey/infection_monkey/network/mysqlfinger.py:61)
# leaving this since there's a TODO related to it
_.get_wmi_info # unused method (monkey/infection_monkey/system_info/windows_info_collector.py:63)
# not 100% sure about these? are these being/will be used somewhere else?
LOG_DIR_NAME # unused variable (envs/monkey_zoo/blackbox/log_handlers/test_logs_handler.py:8)
delete_logs # unused function (envs/monkey_zoo/blackbox/test_blackbox.py:85)
MongoQueryJSONEncoder # unused class (envs/monkey_zoo/blackbox/utils/json_encoder.py:6)