forked from p15670423/monkey
Merge pull request #1786 from guardicore/remove-dead-code
Remove dead code
This commit is contained in:
commit
87a742186a
|
@ -7,6 +7,5 @@ class TelemCategoryEnum:
|
||||||
POST_BREACH = "post_breach"
|
POST_BREACH = "post_breach"
|
||||||
SCAN = "scan"
|
SCAN = "scan"
|
||||||
STATE = "state"
|
STATE = "state"
|
||||||
SYSTEM_INFO = "system_info"
|
|
||||||
TRACE = "trace"
|
TRACE = "trace"
|
||||||
TUNNEL = "tunnel"
|
TUNNEL = "tunnel"
|
||||||
|
|
|
@ -18,10 +18,6 @@ class IncorrectCredentialsError(Exception):
|
||||||
""" Raise to indicate that authentication failed """
|
""" Raise to indicate that authentication failed """
|
||||||
|
|
||||||
|
|
||||||
class InvalidAWSKeys(Exception):
|
|
||||||
""" Raise to indicate that AWS API keys are invalid"""
|
|
||||||
|
|
||||||
|
|
||||||
class NoInternetError(Exception):
|
class NoInternetError(Exception):
|
||||||
""" Raise to indicate problems caused when no internet connection is present"""
|
""" Raise to indicate problems caused when no internet connection is present"""
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class ExploitType(Enum):
|
|
||||||
VULNERABILITY = 1
|
|
||||||
BRUTE_FORCE = 9
|
|
|
@ -83,9 +83,6 @@ class Configuration(object):
|
||||||
# sets whether or not the monkey is alive. if false will stop scanning and exploiting
|
# sets whether or not the monkey is alive. if false will stop scanning and exploiting
|
||||||
alive = True
|
alive = True
|
||||||
|
|
||||||
finger_classes = []
|
|
||||||
exploiter_classes = []
|
|
||||||
|
|
||||||
# depth of propagation
|
# depth of propagation
|
||||||
depth = 2
|
depth = 2
|
||||||
max_depth = None
|
max_depth = None
|
||||||
|
@ -96,39 +93,6 @@ class Configuration(object):
|
||||||
|
|
||||||
keep_tunnel_open_time = 60
|
keep_tunnel_open_time = 60
|
||||||
|
|
||||||
###########################
|
|
||||||
# scanners config
|
|
||||||
###########################
|
|
||||||
|
|
||||||
# Auto detect and scan local subnets
|
|
||||||
local_network_scan = True
|
|
||||||
|
|
||||||
subnet_scan_list = []
|
|
||||||
inaccessible_subnets = []
|
|
||||||
|
|
||||||
blocked_ips = []
|
|
||||||
|
|
||||||
# TCP Scanner
|
|
||||||
HTTP_PORTS = [
|
|
||||||
80,
|
|
||||||
8080,
|
|
||||||
443,
|
|
||||||
8008, # HTTP alternate
|
|
||||||
7001, # Oracle Weblogic default server port
|
|
||||||
]
|
|
||||||
tcp_target_ports = [22, 2222, 445, 135, 3389, 80, 8080, 443, 8008, 3306, 9200]
|
|
||||||
tcp_target_ports.extend(HTTP_PORTS)
|
|
||||||
tcp_scan_timeout = 3000 # 3000 Milliseconds
|
|
||||||
|
|
||||||
# Ping Scanner
|
|
||||||
ping_scan_timeout = 1000
|
|
||||||
|
|
||||||
###########################
|
|
||||||
# ransomware config
|
|
||||||
###########################
|
|
||||||
|
|
||||||
ransomware = ""
|
|
||||||
|
|
||||||
def get_exploit_user_password_pairs(self):
|
def get_exploit_user_password_pairs(self):
|
||||||
"""
|
"""
|
||||||
Returns all combinations of the configurations users and passwords
|
Returns all combinations of the configurations users and passwords
|
||||||
|
@ -136,12 +100,6 @@ class Configuration(object):
|
||||||
"""
|
"""
|
||||||
return product(self.exploit_user_list, self.exploit_password_list)
|
return product(self.exploit_user_list, self.exploit_password_list)
|
||||||
|
|
||||||
def get_exploit_user_ssh_key_pairs(self):
|
|
||||||
"""
|
|
||||||
:return: All combinations of the configurations users and ssh pairs
|
|
||||||
"""
|
|
||||||
return product(self.exploit_user_list, self.exploit_ssh_keys)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hash_sensitive_data(sensitive_data):
|
def hash_sensitive_data(sensitive_data):
|
||||||
"""
|
"""
|
||||||
|
@ -159,11 +117,6 @@ class Configuration(object):
|
||||||
exploit_password_list = ["Password1!", "1234", "password", "12345678"]
|
exploit_password_list = ["Password1!", "1234", "password", "12345678"]
|
||||||
exploit_lm_hash_list = []
|
exploit_lm_hash_list = []
|
||||||
exploit_ntlm_hash_list = []
|
exploit_ntlm_hash_list = []
|
||||||
exploit_ssh_keys = []
|
|
||||||
|
|
||||||
aws_access_key_id = ""
|
|
||||||
aws_secret_access_key = ""
|
|
||||||
aws_session_token = ""
|
|
||||||
|
|
||||||
# smb/wmi exploiter
|
# smb/wmi exploiter
|
||||||
smb_download_timeout = 30 # timeout in seconds
|
smb_download_timeout = 30 # timeout in seconds
|
||||||
|
|
|
@ -21,7 +21,6 @@ from infection_monkey.utils.environment import is_windows_os
|
||||||
requests.packages.urllib3.disable_warnings()
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
DOWNLOAD_CHUNK = 1024
|
|
||||||
|
|
||||||
PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s"
|
PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s"
|
||||||
|
|
||||||
|
@ -133,28 +132,6 @@ class ControlClient(object):
|
||||||
else:
|
else:
|
||||||
ControlClient.proxies["https"] = f"{proxy_address}:{proxy_port}"
|
ControlClient.proxies["https"] = f"{proxy_address}:{proxy_port}"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def keepalive():
|
|
||||||
if not WormConfiguration.current_server:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
monkey = {}
|
|
||||||
if ControlClient.proxies:
|
|
||||||
monkey["tunnel"] = ControlClient.proxies.get("https")
|
|
||||||
requests.patch( # noqa: DUO123
|
|
||||||
"https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID),
|
|
||||||
data=json.dumps(monkey),
|
|
||||||
headers={"content-type": "application/json"},
|
|
||||||
verify=False,
|
|
||||||
proxies=ControlClient.proxies,
|
|
||||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
|
||||||
)
|
|
||||||
except Exception as exc:
|
|
||||||
logger.warning(
|
|
||||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
|
||||||
)
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send_telemetry(telem_category, json_data: str):
|
def send_telemetry(telem_category, json_data: str):
|
||||||
if not WormConfiguration.current_server:
|
if not WormConfiguration.current_server:
|
||||||
|
@ -253,28 +230,6 @@ class ControlClient(object):
|
||||||
)
|
)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_for_stop():
|
|
||||||
ControlClient.load_control_config()
|
|
||||||
return not WormConfiguration.alive
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def spoof_host_os_info(is_windows, is_32bit):
|
|
||||||
if is_windows:
|
|
||||||
os = "windows"
|
|
||||||
if is_32bit:
|
|
||||||
arch = "x86"
|
|
||||||
else:
|
|
||||||
arch = "amd64"
|
|
||||||
else:
|
|
||||||
os = "linux"
|
|
||||||
if is_32bit:
|
|
||||||
arch = "i686"
|
|
||||||
else:
|
|
||||||
arch = "x86_64"
|
|
||||||
|
|
||||||
return {"os": {"type": os, "machine": arch}}
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_control_tunnel():
|
def create_control_tunnel():
|
||||||
if not WormConfiguration.current_server:
|
if not WormConfiguration.current_server:
|
||||||
|
|
|
@ -4,7 +4,6 @@ from datetime import datetime
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from common.utils.exceptions import FailedExploitationError
|
from common.utils.exceptions import FailedExploitationError
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.config import WormConfiguration
|
from infection_monkey.config import WormConfiguration
|
||||||
from infection_monkey.i_puppet import ExploiterResultData
|
from infection_monkey.i_puppet import ExploiterResultData
|
||||||
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
||||||
|
@ -17,15 +16,6 @@ logger = logging.getLogger(__name__)
|
||||||
class HostExploiter:
|
class HostExploiter:
|
||||||
_TARGET_OS_TYPE = []
|
_TARGET_OS_TYPE = []
|
||||||
|
|
||||||
# Usual values are 'vulnerability' or 'brute_force'
|
|
||||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
|
||||||
|
|
||||||
# Determines if successful exploitation should stop further exploit attempts on that machine.
|
|
||||||
# Generally, should be True for RCE type exploiters and False if we don't expect the
|
|
||||||
# exploiter to run the monkey agent.
|
|
||||||
# Example: Zerologon steals credentials
|
|
||||||
RUNS_AGENT_ON_SUCCESS = True
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def _EXPLOITED_SERVICE(self):
|
def _EXPLOITED_SERVICE(self):
|
||||||
|
|
|
@ -22,7 +22,7 @@ class CachingAgentRepository(IAgentRepository):
|
||||||
self._proxies = proxies
|
self._proxies = proxies
|
||||||
self._lock = threading.Lock()
|
self._lock = threading.Lock()
|
||||||
|
|
||||||
def get_agent_binary(self, os: str, _: str = None) -> io.BytesIO:
|
def get_agent_binary(self, os: str, architecture: str = None) -> io.BytesIO:
|
||||||
# If multiple calls to get_agent_binary() are made simultaneously before the result of
|
# If multiple calls to get_agent_binary() are made simultaneously before the result of
|
||||||
# _download_binary_from_island() is cached, then multiple requests will be sent to the
|
# _download_binary_from_island() is cached, then multiple requests will be sent to the
|
||||||
# island. Add a mutex in front of the call to _download_agent_binary_from_island() so
|
# island. Add a mutex in front of the call to _download_agent_binary_from_island() so
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.log4shell_utils import (
|
from infection_monkey.exploit.log4shell_utils import (
|
||||||
LINUX_EXPLOIT_TEMPLATE_PATH,
|
LINUX_EXPLOIT_TEMPLATE_PATH,
|
||||||
WINDOWS_EXPLOIT_TEMPLATE_PATH,
|
WINDOWS_EXPLOIT_TEMPLATE_PATH,
|
||||||
|
@ -25,7 +24,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Log4ShellExploiter(WebRCE):
|
class Log4ShellExploiter(WebRCE):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
_TARGET_OS_TYPE = ["linux", "windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
|
||||||
_EXPLOITED_SERVICE = "Log4j"
|
_EXPLOITED_SERVICE = "Log4j"
|
||||||
SERVER_SHUTDOWN_TIMEOUT = 15
|
SERVER_SHUTDOWN_TIMEOUT = 15
|
||||||
REQUEST_TO_VICTIM_TIMEOUT = (
|
REQUEST_TO_VICTIM_TIMEOUT = (
|
||||||
|
|
|
@ -6,7 +6,6 @@ import pymssql
|
||||||
|
|
||||||
from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT
|
from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT
|
||||||
from common.utils.exceptions import FailedExploitationError
|
from common.utils.exceptions import FailedExploitationError
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_agent_dest_path
|
from infection_monkey.exploit.tools.helpers import get_agent_dest_path
|
||||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||||
|
@ -23,7 +22,6 @@ logger = logging.getLogger(__name__)
|
||||||
class MSSQLExploiter(HostExploiter):
|
class MSSQLExploiter(HostExploiter):
|
||||||
_EXPLOITED_SERVICE = "MSSQL"
|
_EXPLOITED_SERVICE = "MSSQL"
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
_TARGET_OS_TYPE = ["windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
|
||||||
LOGIN_TIMEOUT = 15
|
LOGIN_TIMEOUT = 15
|
||||||
# Time in seconds to wait between MSSQL queries.
|
# Time in seconds to wait between MSSQL queries.
|
||||||
QUERY_BUFFER = 0.5
|
QUERY_BUFFER = 0.5
|
||||||
|
|
|
@ -2,7 +2,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.powershell_utils.auth_options import (
|
from infection_monkey.exploit.powershell_utils.auth_options import (
|
||||||
AUTH_NEGOTIATE,
|
AUTH_NEGOTIATE,
|
||||||
|
@ -42,7 +41,6 @@ class RemoteAgentExecutionError(Exception):
|
||||||
|
|
||||||
class PowerShellExploiter(HostExploiter):
|
class PowerShellExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
_TARGET_OS_TYPE = ["windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
|
||||||
_EXPLOITED_SERVICE = "PowerShell Remoting (WinRM)"
|
_EXPLOITED_SERVICE = "PowerShell Remoting (WinRM)"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -3,7 +3,6 @@ from logging import getLogger
|
||||||
from impacket.dcerpc.v5 import scmr, transport
|
from impacket.dcerpc.v5 import scmr, transport
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus, UsageEnum
|
from common.utils.attack_utils import ScanStatus, UsageEnum
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey
|
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey
|
||||||
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
||||||
|
@ -18,7 +17,6 @@ logger = getLogger(__name__)
|
||||||
|
|
||||||
class SmbExploiter(HostExploiter):
|
class SmbExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
_TARGET_OS_TYPE = ["windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
|
||||||
_EXPLOITED_SERVICE = "SMB"
|
_EXPLOITED_SERVICE = "SMB"
|
||||||
KNOWN_PROTOCOLS = {
|
KNOWN_PROTOCOLS = {
|
||||||
"139/SMB": (r"ncacn_np:%s[\pipe\svcctl]", 139),
|
"139/SMB": (r"ncacn_np:%s[\pipe\svcctl]", 139),
|
||||||
|
|
|
@ -6,7 +6,6 @@ import paramiko
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus
|
from common.utils.attack_utils import ScanStatus
|
||||||
from common.utils.exceptions import FailedExploitationError
|
from common.utils.exceptions import FailedExploitationError
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.i_puppet import ExploiterResultData
|
from infection_monkey.i_puppet import ExploiterResultData
|
||||||
from infection_monkey.model import MONKEY_ARG
|
from infection_monkey.model import MONKEY_ARG
|
||||||
|
@ -23,7 +22,6 @@ TRANSFER_UPDATE_RATE = 15
|
||||||
|
|
||||||
class SSHExploiter(HostExploiter):
|
class SSHExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["linux", None]
|
_TARGET_OS_TYPE = ["linux", None]
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
|
||||||
_EXPLOITED_SERVICE = "SSH"
|
_EXPLOITED_SERVICE = "SSH"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -19,12 +19,6 @@ def get_target_monkey(host):
|
||||||
raise NotImplementedError("get_target_monkey() has been retired. Use IAgentRepository instead.")
|
raise NotImplementedError("get_target_monkey() has been retired. Use IAgentRepository instead.")
|
||||||
|
|
||||||
|
|
||||||
def get_target_monkey_by_os(is_windows, is_32bit):
|
|
||||||
raise NotImplementedError(
|
|
||||||
"get_target_monkey_by_os() has been retired. Use IAgentRepository instead."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_random_file_suffix() -> str:
|
def get_random_file_suffix() -> str:
|
||||||
character_set = list(string.ascii_letters + string.digits + "_" + "-")
|
character_set = list(string.ascii_letters + string.digits + "_" + "-")
|
||||||
# random.SystemRandom can block indefinitely in Linux
|
# random.SystemRandom can block indefinitely in Linux
|
||||||
|
|
|
@ -5,7 +5,6 @@ from typing import List, Tuple
|
||||||
|
|
||||||
from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus
|
from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey
|
|
||||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||||
from infection_monkey.model import (
|
from infection_monkey.model import (
|
||||||
BITSADMIN_CMDLINE_HTTP,
|
BITSADMIN_CMDLINE_HTTP,
|
||||||
|
@ -407,51 +406,6 @@ class WebRCE(HostExploiter):
|
||||||
self.add_executed_cmd(command)
|
self.add_executed_cmd(command)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def get_monkey_upload_path(self, url_to_monkey):
|
|
||||||
"""
|
|
||||||
Gets destination path from one of WEB_RCE predetermined paths(self.monkey_target_paths).
|
|
||||||
:param url_to_monkey: Hosted monkey's url. egz :
|
|
||||||
http://localserver:9999/monkey/windows-64.exe
|
|
||||||
:return: Corresponding monkey path from self.monkey_target_paths
|
|
||||||
"""
|
|
||||||
if not url_to_monkey or ("linux" not in url_to_monkey and "windows" not in url_to_monkey):
|
|
||||||
logger.error(
|
|
||||||
"Can't get destination path because source path %s is invalid.", url_to_monkey
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
if "linux" in url_to_monkey:
|
|
||||||
return self.monkey_target_paths["linux"]
|
|
||||||
elif "windows" in url_to_monkey:
|
|
||||||
return self.monkey_target_paths["win64"]
|
|
||||||
else:
|
|
||||||
logger.error(
|
|
||||||
"Could not figure out what type of monkey server was trying to upload, "
|
|
||||||
"thus destination path can not be chosen."
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
except KeyError:
|
|
||||||
logger.error(
|
|
||||||
'Unknown key was found. Please use "linux" and "win64" keys to '
|
|
||||||
"initialize custom dict of monkey's destination paths"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_monkey_paths(self):
|
|
||||||
"""
|
|
||||||
Gets local (used by server) and destination (where to download) paths.
|
|
||||||
:return: dict of source and destination paths
|
|
||||||
"""
|
|
||||||
src_path = get_target_monkey(self.host)
|
|
||||||
if not src_path:
|
|
||||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
|
||||||
return False
|
|
||||||
# Determine which destination path to use
|
|
||||||
dest_path = self.get_monkey_upload_path(src_path)
|
|
||||||
if not dest_path:
|
|
||||||
return False
|
|
||||||
return {"src_path": src_path, "dest_path": dest_path}
|
|
||||||
|
|
||||||
def get_default_dropper_path(self):
|
def get_default_dropper_path(self):
|
||||||
"""
|
"""
|
||||||
Gets default dropper path for the host.
|
Gets default dropper path for the host.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import traceback
|
||||||
|
|
||||||
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
||||||
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
||||||
from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException, WmiTools
|
from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException, WmiTools
|
||||||
|
@ -22,7 +21,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class WmiExploiter(HostExploiter):
|
class WmiExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
_TARGET_OS_TYPE = ["windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
|
||||||
_EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)"
|
_EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)"
|
||||||
|
|
||||||
@WmiTools.impacket_user
|
@WmiTools.impacket_user
|
||||||
|
|
|
@ -15,7 +15,6 @@ import impacket
|
||||||
from impacket.dcerpc.v5 import epm, nrpc, rpcrt, transport
|
from impacket.dcerpc.v5 import epm, nrpc, rpcrt, transport
|
||||||
from impacket.dcerpc.v5.dtypes import NULL
|
from impacket.dcerpc.v5.dtypes import NULL
|
||||||
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from infection_monkey.credential_collectors import LMHash, NTHash, Username
|
from infection_monkey.credential_collectors import LMHash, NTHash, Username
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.wmi_tools import WmiTools
|
from infection_monkey.exploit.tools.wmi_tools import WmiTools
|
||||||
|
@ -34,8 +33,6 @@ logger = logging.getLogger(__name__)
|
||||||
class ZerologonExploiter(HostExploiter):
|
class ZerologonExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
_TARGET_OS_TYPE = ["windows"]
|
||||||
_EXPLOITED_SERVICE = "Netlogon"
|
_EXPLOITED_SERVICE = "Netlogon"
|
||||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
|
||||||
RUNS_AGENT_ON_SUCCESS = False
|
|
||||||
MAX_ATTEMPTS = 2000 # For 2000, expected average number of attempts needed: 256.
|
MAX_ATTEMPTS = 2000 # For 2000, expected average number of attempts needed: 256.
|
||||||
ERROR_CODE_ACCESS_DENIED = 0xC0000022
|
ERROR_CODE_ACCESS_DENIED = 0xC0000022
|
||||||
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
from infection_monkey.model.host import VictimHost
|
|
||||||
|
|
||||||
|
|
||||||
class VictimHostGenerator(object):
|
|
||||||
def __init__(self, network_ranges, blocked_ips, same_machine_ips):
|
|
||||||
self.blocked_ips = blocked_ips
|
|
||||||
self.ranges = network_ranges
|
|
||||||
self.local_addresses = same_machine_ips
|
|
||||||
|
|
||||||
def generate_victims(self, chunk_size):
|
|
||||||
"""
|
|
||||||
Generates VictimHosts in chunks from all the instances network ranges
|
|
||||||
:param chunk_size: Maximum size of each chunk
|
|
||||||
"""
|
|
||||||
chunk = []
|
|
||||||
for net_range in self.ranges:
|
|
||||||
for victim in self.generate_victims_from_range(net_range):
|
|
||||||
chunk.append(victim)
|
|
||||||
if len(chunk) == chunk_size:
|
|
||||||
yield chunk
|
|
||||||
chunk = []
|
|
||||||
if chunk: # finished with number of victims < chunk_size
|
|
||||||
yield chunk
|
|
||||||
|
|
||||||
def generate_victims_from_range(self, net_range):
|
|
||||||
"""
|
|
||||||
Generates VictimHosts from a given netrange
|
|
||||||
:param net_range: Network range object
|
|
||||||
:return: Generator of VictimHost objects
|
|
||||||
"""
|
|
||||||
for address in net_range:
|
|
||||||
if not self.is_ip_scannable(address): # check if the IP should be skipped
|
|
||||||
continue
|
|
||||||
if hasattr(net_range, "domain_name"):
|
|
||||||
victim = VictimHost(address, net_range.domain_name)
|
|
||||||
else:
|
|
||||||
victim = VictimHost(address)
|
|
||||||
yield victim
|
|
||||||
|
|
||||||
def is_ip_scannable(self, ip_address):
|
|
||||||
if ip_address in self.local_addresses:
|
|
||||||
return False
|
|
||||||
if ip_address in self.blocked_ips:
|
|
||||||
return False
|
|
||||||
return True
|
|
|
@ -9,11 +9,9 @@ from typing import List
|
||||||
import netifaces
|
import netifaces
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from common.network.network_range import CidrRange
|
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
# Timeout for monkey connections
|
# Timeout for monkey connections
|
||||||
TIMEOUT = 15
|
|
||||||
LOOPBACK_NAME = b"lo"
|
LOOPBACK_NAME = b"lo"
|
||||||
SIOCGIFADDR = 0x8915 # get PA address
|
SIOCGIFADDR = 0x8915 # get PA address
|
||||||
SIOCGIFNETMASK = 0x891B # get network PA mask
|
SIOCGIFNETMASK = 0x891B # get network PA mask
|
||||||
|
@ -137,19 +135,3 @@ def get_free_tcp_port(min_range=1024, max_range=65535):
|
||||||
return port
|
return port
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_interfaces_ranges():
|
|
||||||
"""
|
|
||||||
Returns a list of IPs accessible in the host in each network interface, in the subnet.
|
|
||||||
Limits to a single class C if the network is larger
|
|
||||||
:return: List of IPs, marked as strings.
|
|
||||||
"""
|
|
||||||
res = []
|
|
||||||
ifs = get_host_subnets()
|
|
||||||
for net_interface in ifs:
|
|
||||||
address_str = net_interface["addr"]
|
|
||||||
netmask_str = net_interface["netmask"]
|
|
||||||
# limit subnet scans to class C only
|
|
||||||
res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str)))
|
|
||||||
return res
|
|
||||||
|
|
|
@ -12,32 +12,6 @@ BANNER_READ = 1024
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def struct_unpack_tracker(data, index, fmt):
|
|
||||||
"""
|
|
||||||
Unpacks a struct from the specified index according to specified format.
|
|
||||||
Returns the data and the next index
|
|
||||||
:param data: Buffer
|
|
||||||
:param index: Position index
|
|
||||||
:param fmt: Struct format
|
|
||||||
:return: (Data, new index)
|
|
||||||
"""
|
|
||||||
unpacked = struct.unpack_from(fmt, data, index)
|
|
||||||
return unpacked, struct.calcsize(fmt)
|
|
||||||
|
|
||||||
|
|
||||||
def struct_unpack_tracker_string(data, index):
|
|
||||||
"""
|
|
||||||
Unpacks a null terminated string from the specified index
|
|
||||||
Returns the data and the next index
|
|
||||||
:param data: Buffer
|
|
||||||
:param index: Position index
|
|
||||||
:return: (Data, new index)
|
|
||||||
"""
|
|
||||||
ascii_len = data[index:].find(b"\0")
|
|
||||||
fmt = "%ds" % ascii_len
|
|
||||||
return struct_unpack_tracker(data, index, fmt)
|
|
||||||
|
|
||||||
|
|
||||||
def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
||||||
"""
|
"""
|
||||||
Checks if a given TCP port is open
|
Checks if a given TCP port is open
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
from common.network.network_range import CidrRange, SingleIpRange
|
|
||||||
from infection_monkey.model.victim_host_generator import VictimHostGenerator
|
|
||||||
|
|
||||||
|
|
||||||
class TestVictimHostGenerator(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.cidr_range = CidrRange("10.0.0.0/28", False) # this gives us 15 hosts
|
|
||||||
self.local_host_range = SingleIpRange("localhost")
|
|
||||||
self.random_single_ip_range = SingleIpRange("41.50.13.37")
|
|
||||||
|
|
||||||
def test_chunking(self):
|
|
||||||
chunk_size = 3
|
|
||||||
# current test setup is 15+1+1-1 hosts
|
|
||||||
test_ranges = [self.cidr_range, self.local_host_range, self.random_single_ip_range]
|
|
||||||
generator = VictimHostGenerator(test_ranges, "10.0.0.1", [])
|
|
||||||
victims = generator.generate_victims(chunk_size)
|
|
||||||
for i in range(5): # quickly check the equally sided chunks
|
|
||||||
self.assertEqual(len(next(victims)), chunk_size)
|
|
||||||
victim_chunk_last = next(victims)
|
|
||||||
self.assertEqual(len(victim_chunk_last), 1)
|
|
||||||
|
|
||||||
def test_remove_blocked_ip(self):
|
|
||||||
generator = VictimHostGenerator(self.cidr_range, ["10.0.0.1"], [])
|
|
||||||
|
|
||||||
victims = list(generator.generate_victims_from_range(self.cidr_range))
|
|
||||||
self.assertEqual(len(victims), 14) # 15 minus the 1 we blocked
|
|
||||||
|
|
||||||
def test_remove_local_ips(self):
|
|
||||||
generator = VictimHostGenerator([], [], [])
|
|
||||||
generator.local_addresses = ["127.0.0.1"]
|
|
||||||
victims = list(generator.generate_victims_from_range(self.local_host_range))
|
|
||||||
self.assertEqual(len(victims), 0) # block the local IP
|
|
||||||
|
|
||||||
def test_generate_domain_victim(self):
|
|
||||||
# domain name victim
|
|
||||||
generator = VictimHostGenerator([], [], []) # dummy object
|
|
||||||
victims = list(generator.generate_victims_from_range(self.local_host_range))
|
|
||||||
self.assertEqual(len(victims), 1)
|
|
||||||
self.assertEqual(victims[0].domain_name, "localhost")
|
|
|
@ -146,6 +146,7 @@ Report.glance
|
||||||
Report.meta_info
|
Report.meta_info
|
||||||
Report.meta
|
Report.meta
|
||||||
LDAPServerFactory.buildProtocol
|
LDAPServerFactory.buildProtocol
|
||||||
|
get_file_sha256_hash
|
||||||
|
|
||||||
# these are not needed for it to work, but may be useful extra information to understand what's going on
|
# 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_PBA_TYPE # unused variable (monkey/monkey_island/cc/resources/pba_file_upload.py:23)
|
||||||
|
@ -166,6 +167,7 @@ _.environment # unused attribute (monkey/monkey_island/cc/services/telemetry/pr
|
||||||
_.instance_name # unused attribute (monkey/common/cloud/azure/azure_instance.py:35)
|
_.instance_name # unused attribute (monkey/common/cloud/azure/azure_instance.py:35)
|
||||||
_.instance_name # unused attribute (monkey/common/cloud/azure/azure_instance.py:64)
|
_.instance_name # unused attribute (monkey/common/cloud/azure/azure_instance.py:64)
|
||||||
GCPHandler # unused function (envs/monkey_zoo/blackbox/test_blackbox.py:57)
|
GCPHandler # unused function (envs/monkey_zoo/blackbox/test_blackbox.py:57)
|
||||||
|
architecture # unused variable (monkey/infection_monkey/exploit/caching_agent_repository.py:25)
|
||||||
|
|
||||||
# TODO: Reevaluate these as the agent refactor progresses
|
# TODO: Reevaluate these as the agent refactor progresses
|
||||||
run_sys_info_collector
|
run_sys_info_collector
|
||||||
|
|
Loading…
Reference in New Issue