forked from p15670423/monkey
Merge branch 'develop' into bugfix/remove_warnings
This commit is contained in:
commit
1a7c5b951a
|
@ -2,11 +2,9 @@ import hashlib
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import types
|
|
||||||
import uuid
|
import uuid
|
||||||
from abc import ABCMeta
|
from abc import ABCMeta
|
||||||
from itertools import product
|
from itertools import product
|
||||||
import importlib
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
@ -20,10 +18,6 @@ HIDDEN_FIELD_REPLACEMENT_CONTENT = "hidden"
|
||||||
|
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
def from_kv(self, formatted_data):
|
def from_kv(self, formatted_data):
|
||||||
# now we won't work at <2.7 for sure
|
|
||||||
network_import = importlib.import_module('infection_monkey.network')
|
|
||||||
exploit_import = importlib.import_module('infection_monkey.exploit')
|
|
||||||
|
|
||||||
unknown_items = []
|
unknown_items = []
|
||||||
for key, value in list(formatted_data.items()):
|
for key, value in list(formatted_data.items()):
|
||||||
if key.startswith('_'):
|
if key.startswith('_'):
|
||||||
|
@ -32,11 +26,6 @@ class Configuration(object):
|
||||||
continue
|
continue
|
||||||
if self._depth_from_commandline and key == "depth":
|
if self._depth_from_commandline and key == "depth":
|
||||||
continue
|
continue
|
||||||
# handle in cases
|
|
||||||
elif key == 'exploiter_classes':
|
|
||||||
class_objects = [getattr(exploit_import, val) for val in value]
|
|
||||||
setattr(self, key, class_objects)
|
|
||||||
else:
|
|
||||||
if hasattr(self, key):
|
if hasattr(self, key):
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from infection_monkey.config import WormConfiguration
|
||||||
|
from common.utils.exploit_enum import ExploitType
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from infection_monkey.utils.plugins.plugin import Plugin
|
||||||
|
import infection_monkey.exploit
|
||||||
|
|
||||||
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
|
||||||
|
class HostExploiter(Plugin):
|
||||||
|
@staticmethod
|
||||||
|
def should_run(class_name):
|
||||||
|
"""
|
||||||
|
Decides if post breach action is enabled in config
|
||||||
|
:return: True if it needs to be ran, false otherwise
|
||||||
|
"""
|
||||||
|
return class_name in WormConfiguration.exploiter_classes
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def base_package_file():
|
||||||
|
return infection_monkey.exploit.__file__
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def base_package_name():
|
||||||
|
return infection_monkey.exploit.__package__
|
||||||
|
|
||||||
|
_TARGET_OS_TYPE = []
|
||||||
|
|
||||||
|
# Usual values are 'vulnerability' or 'brute_force'
|
||||||
|
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def _EXPLOITED_SERVICE(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, host):
|
||||||
|
self._config = WormConfiguration
|
||||||
|
self.exploit_info = {'display_name': self._EXPLOITED_SERVICE,
|
||||||
|
'started': '',
|
||||||
|
'finished': '',
|
||||||
|
'vulnerable_urls': [],
|
||||||
|
'vulnerable_ports': [],
|
||||||
|
'executed_cmds': []}
|
||||||
|
self.exploit_attempts = []
|
||||||
|
self.host = host
|
||||||
|
|
||||||
|
def set_start_time(self):
|
||||||
|
self.exploit_info['started'] = datetime.now().isoformat()
|
||||||
|
|
||||||
|
def set_finish_time(self):
|
||||||
|
self.exploit_info['finished'] = datetime.now().isoformat()
|
||||||
|
|
||||||
|
def is_os_supported(self):
|
||||||
|
return self.host.os.get('type') in self._TARGET_OS_TYPE
|
||||||
|
|
||||||
|
def send_exploit_telemetry(self, result):
|
||||||
|
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
||||||
|
ExploitTelem(self, result).send()
|
||||||
|
|
||||||
|
def report_login_attempt(self, result, user, password='', lm_hash='', ntlm_hash='', ssh_key=''):
|
||||||
|
self.exploit_attempts.append({'result': result, 'user': user, 'password': password,
|
||||||
|
'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key})
|
||||||
|
|
||||||
|
def exploit_host(self):
|
||||||
|
self.pre_exploit()
|
||||||
|
try:
|
||||||
|
result = self._exploit_host()
|
||||||
|
finally:
|
||||||
|
self.post_exploit()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def pre_exploit(self):
|
||||||
|
self.set_start_time()
|
||||||
|
|
||||||
|
def post_exploit(self):
|
||||||
|
self.set_finish_time()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _exploit_host(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def add_vuln_url(self, url):
|
||||||
|
self.exploit_info['vulnerable_urls'].append(url)
|
||||||
|
|
||||||
|
def add_vuln_port(self, port):
|
||||||
|
self.exploit_info['vulnerable_ports'].append(port)
|
||||||
|
|
||||||
|
def add_executed_cmd(self, cmd):
|
||||||
|
"""
|
||||||
|
Appends command to exploiter's info.
|
||||||
|
:param cmd: String of executed command. e.g. 'echo Example'
|
||||||
|
"""
|
||||||
|
powershell = True if "powershell" in cmd.lower() else False
|
||||||
|
self.exploit_info['executed_cmds'].append({'cmd': cmd, 'powershell': powershell})
|
|
@ -1,92 +0,0 @@
|
||||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
|
||||||
import infection_monkey.config
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
|
|
||||||
class HostExploiter(object, metaclass=ABCMeta):
|
|
||||||
_TARGET_OS_TYPE = []
|
|
||||||
|
|
||||||
# Usual values are 'vulnerability' or 'brute_force'
|
|
||||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
|
||||||
|
|
||||||
@property
|
|
||||||
@abstractmethod
|
|
||||||
def _EXPLOITED_SERVICE(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __init__(self, host):
|
|
||||||
self._config = infection_monkey.config.WormConfiguration
|
|
||||||
self.exploit_info = {'display_name': self._EXPLOITED_SERVICE,
|
|
||||||
'started': '',
|
|
||||||
'finished': '',
|
|
||||||
'vulnerable_urls': [],
|
|
||||||
'vulnerable_ports': [],
|
|
||||||
'executed_cmds': []}
|
|
||||||
self.exploit_attempts = []
|
|
||||||
self.host = host
|
|
||||||
|
|
||||||
def set_start_time(self):
|
|
||||||
self.exploit_info['started'] = datetime.now().isoformat()
|
|
||||||
|
|
||||||
def set_finish_time(self):
|
|
||||||
self.exploit_info['finished'] = datetime.now().isoformat()
|
|
||||||
|
|
||||||
def is_os_supported(self):
|
|
||||||
return self.host.os.get('type') in self._TARGET_OS_TYPE
|
|
||||||
|
|
||||||
def send_exploit_telemetry(self, result):
|
|
||||||
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
|
||||||
ExploitTelem(self, result).send()
|
|
||||||
|
|
||||||
def report_login_attempt(self, result, user, password='', lm_hash='', ntlm_hash='', ssh_key=''):
|
|
||||||
self.exploit_attempts.append({'result': result, 'user': user, 'password': password,
|
|
||||||
'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key})
|
|
||||||
|
|
||||||
def exploit_host(self):
|
|
||||||
self.pre_exploit()
|
|
||||||
try:
|
|
||||||
result = self._exploit_host()
|
|
||||||
finally:
|
|
||||||
self.post_exploit()
|
|
||||||
return result
|
|
||||||
|
|
||||||
def pre_exploit(self):
|
|
||||||
self.set_start_time()
|
|
||||||
|
|
||||||
def post_exploit(self):
|
|
||||||
self.set_finish_time()
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def _exploit_host(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def add_vuln_url(self, url):
|
|
||||||
self.exploit_info['vulnerable_urls'].append(url)
|
|
||||||
|
|
||||||
def add_vuln_port(self, port):
|
|
||||||
self.exploit_info['vulnerable_ports'].append(port)
|
|
||||||
|
|
||||||
def add_executed_cmd(self, cmd):
|
|
||||||
"""
|
|
||||||
Appends command to exploiter's info.
|
|
||||||
:param cmd: String of executed command. e.g. 'echo Example'
|
|
||||||
"""
|
|
||||||
powershell = True if "powershell" in cmd.lower() else False
|
|
||||||
self.exploit_info['executed_cmds'].append({'cmd': cmd, 'powershell': powershell})
|
|
||||||
|
|
||||||
|
|
||||||
from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter
|
|
||||||
from infection_monkey.exploit.wmiexec import WmiExploiter
|
|
||||||
from infection_monkey.exploit.smbexec import SmbExploiter
|
|
||||||
from infection_monkey.exploit.sshexec import SSHExploiter
|
|
||||||
from infection_monkey.exploit.shellshock import ShellShockExploiter
|
|
||||||
from infection_monkey.exploit.sambacry import SambaCryExploiter
|
|
||||||
from infection_monkey.exploit.elasticgroovy import ElasticGroovyExploiter
|
|
||||||
from infection_monkey.exploit.struts2 import Struts2Exploiter
|
|
||||||
from infection_monkey.exploit.weblogic import WebLogicExploiter
|
|
||||||
from infection_monkey.exploit.hadoop import HadoopExploiter
|
|
||||||
from infection_monkey.exploit.mssqlexec import MSSQLExploiter
|
|
||||||
from infection_monkey.exploit.vsftpd import VSFTPDExploiter
|
|
|
@ -6,7 +6,7 @@ from time import sleep
|
||||||
import pymssql
|
import pymssql
|
||||||
|
|
||||||
from common.utils.exploit_enum import ExploitType
|
from common.utils.exploit_enum import ExploitType
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.http_tools import MonkeyHTTPServer
|
from infection_monkey.exploit.tools.http_tools import MonkeyHTTPServer
|
||||||
from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, build_monkey_commandline, get_monkey_depth
|
from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, build_monkey_commandline, get_monkey_depth
|
||||||
from infection_monkey.model import DROPPER_ARG
|
from infection_monkey.model import DROPPER_ARG
|
||||||
|
|
|
@ -16,7 +16,7 @@ from impacket.smb3structs import SMB2_IL_IMPERSONATION, SMB2_CREATE, SMB2_FLAGS_
|
||||||
from impacket.smbconnection import SMBConnection
|
from impacket.smbconnection import SMBConnection
|
||||||
|
|
||||||
import infection_monkey.monkeyfs as monkeyfs
|
import infection_monkey.monkeyfs as monkeyfs
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.model import DROPPER_ARG
|
from infection_monkey.model import DROPPER_ARG
|
||||||
from infection_monkey.network.smbfinger import SMB_SERVICE
|
from infection_monkey.network.smbfinger import SMB_SERVICE
|
||||||
from infection_monkey.exploit.tools.helpers import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth
|
from infection_monkey.exploit.tools.helpers import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth
|
||||||
|
|
|
@ -7,7 +7,7 @@ from random import choice
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus
|
from common.utils.attack_utils import ScanStatus
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
||||||
from infection_monkey.model import DROPPER_ARG
|
from infection_monkey.model import DROPPER_ARG
|
||||||
from infection_monkey.exploit.shellshock_resources import CGI_FILES
|
from infection_monkey.exploit.shellshock_resources import CGI_FILES
|
||||||
|
|
|
@ -3,7 +3,7 @@ from logging import getLogger
|
||||||
from impacket.dcerpc.v5 import transport, scmr
|
from impacket.dcerpc.v5 import transport, scmr
|
||||||
from impacket.smbconnection import SMB_DIALECT
|
from impacket.smbconnection import SMB_DIALECT
|
||||||
|
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
||||||
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
from infection_monkey.exploit.tools.smb_tools import SmbTools
|
||||||
from infection_monkey.model import MONKEY_CMDLINE_DETACHED_WINDOWS, DROPPER_CMDLINE_DETACHED_WINDOWS
|
from infection_monkey.model import MONKEY_CMDLINE_DETACHED_WINDOWS, DROPPER_CMDLINE_DETACHED_WINDOWS
|
||||||
|
|
|
@ -5,7 +5,7 @@ import time
|
||||||
import paramiko
|
import paramiko
|
||||||
|
|
||||||
import infection_monkey.monkeyfs as monkeyfs
|
import infection_monkey.monkeyfs as monkeyfs
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
||||||
from infection_monkey.model import MONKEY_ARG
|
from infection_monkey.model import MONKEY_ARG
|
||||||
from infection_monkey.network.tools import check_tcp_port, get_interface_to_target
|
from infection_monkey.network.tools import check_tcp_port, get_interface_to_target
|
||||||
|
|
|
@ -8,7 +8,7 @@ import socket
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus
|
from common.utils.attack_utils import ScanStatus
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, build_monkey_commandline, get_monkey_depth
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, build_monkey_commandline, get_monkey_depth
|
||||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||||
from infection_monkey.model import MONKEY_ARG, CHMOD_MONKEY, RUN_MONKEY, WGET_HTTP_UPLOAD, DOWNLOAD_TIMEOUT
|
from infection_monkey.model import MONKEY_ARG, CHMOD_MONKEY, RUN_MONKEY, WGET_HTTP_UPLOAD, DOWNLOAD_TIMEOUT
|
||||||
|
|
|
@ -3,7 +3,7 @@ import re
|
||||||
from posixpath import join
|
from posixpath import join
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
||||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||||
from infection_monkey.model import CHECK_COMMAND, ID_STRING, GET_ARCH_LINUX, GET_ARCH_WINDOWS, BITSADMIN_CMDLINE_HTTP, \
|
from infection_monkey.model import CHECK_COMMAND, ID_STRING, GET_ARCH_LINUX, GET_ARCH_WINDOWS, BITSADMIN_CMDLINE_HTTP, \
|
||||||
|
|
|
@ -7,7 +7,7 @@ from requests import post, exceptions
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
from infection_monkey.exploit.web_rce import WebRCE
|
from infection_monkey.exploit.web_rce import WebRCE
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.network.tools import get_interface_to_target
|
from infection_monkey.network.tools import get_interface_to_target
|
||||||
from infection_monkey.network.info import get_free_tcp_port
|
from infection_monkey.network.info import get_free_tcp_port
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
|
@ -19,7 +19,7 @@ from infection_monkey.exploit.tools.smb_tools import SmbTools
|
||||||
from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
|
from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
|
||||||
from infection_monkey.network.smbfinger import SMBFinger
|
from infection_monkey.network.smbfinger import SMBFinger
|
||||||
from infection_monkey.network.tools import check_tcp_port
|
from infection_monkey.network.tools import check_tcp_port
|
||||||
from . import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
|
|
||||||
LOG = getLogger(__name__)
|
LOG = getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import traceback
|
||||||
|
|
||||||
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
||||||
|
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import get_target_monkey, \
|
from infection_monkey.exploit.tools.helpers import get_target_monkey, \
|
||||||
get_monkey_depth, build_monkey_commandline
|
get_monkey_depth, build_monkey_commandline
|
||||||
from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException
|
from infection_monkey.exploit.tools.wmi_tools import AccessDeniedException
|
||||||
|
|
|
@ -30,6 +30,7 @@ from infection_monkey.network.tools import get_interface_to_target
|
||||||
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||||
from infection_monkey.telemetry.attack.t1106_telem import T1106Telem
|
from infection_monkey.telemetry.attack.t1106_telem import T1106Telem
|
||||||
from common.utils.attack_utils import ScanStatus, UsageEnum
|
from common.utils.attack_utils import ScanStatus, UsageEnum
|
||||||
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
@ -144,10 +145,10 @@ class InfectionMonkey(object):
|
||||||
|
|
||||||
self._network.initialize()
|
self._network.initialize()
|
||||||
|
|
||||||
self._exploiters = WormConfiguration.exploiter_classes
|
|
||||||
|
|
||||||
self._fingerprint = HostFinger.get_instances()
|
self._fingerprint = HostFinger.get_instances()
|
||||||
|
|
||||||
|
self._exploiters = HostExploiter.get_classes()
|
||||||
|
|
||||||
if not self._keep_running or not WormConfiguration.alive:
|
if not self._keep_running or not WormConfiguration.alive:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
from PyInstaller.utils.hooks import collect_submodules, collect_data_files
|
||||||
|
|
||||||
|
hiddenimports = collect_submodules('infection_monkey.exploit')
|
||||||
|
datas = (collect_data_files('infection_monkey.exploit', include_py_files=True))
|
|
@ -4,7 +4,7 @@ import logging
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from os.path import dirname, basename, isfile, join
|
from os.path import dirname, basename, isfile, join
|
||||||
import glob
|
import glob
|
||||||
from typing import Sequence, TypeVar, Type
|
from typing import Sequence, TypeVar, Type, Callable
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ def _get_candidate_files(base_package_file):
|
||||||
return [basename(f)[:-3] for f in files if isfile(f) and not f.endswith('__init__.py')]
|
return [basename(f)[:-3] for f in files if isfile(f) and not f.endswith('__init__.py')]
|
||||||
|
|
||||||
|
|
||||||
Plugin_type = TypeVar('Plugin_type', bound='Plugin')
|
PluginType = TypeVar('PluginType', bound='Plugin')
|
||||||
|
|
||||||
|
|
||||||
class Plugin(metaclass=ABCMeta):
|
class Plugin(metaclass=ABCMeta):
|
||||||
|
@ -25,11 +25,11 @@ class Plugin(metaclass=ABCMeta):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_instances(cls) -> Sequence[Type[Plugin_type]]:
|
def get_classes(cls) -> Sequence[Callable]:
|
||||||
"""
|
"""
|
||||||
Returns the type objects from base_package_spec.
|
Returns the class objects from base_package_spec
|
||||||
base_package name and file must refer to the same package otherwise bad results
|
base_package name and file must refer to the same package otherwise bad results
|
||||||
:return: A list of parent_class objects.
|
:return: A list of parent_class classes.
|
||||||
"""
|
"""
|
||||||
objects = []
|
objects = []
|
||||||
candidate_files = _get_candidate_files(cls.base_package_file())
|
candidate_files = _get_candidate_files(cls.base_package_file())
|
||||||
|
@ -47,13 +47,29 @@ class Plugin(metaclass=ABCMeta):
|
||||||
LOG.debug("Checking if should run object {}".format(class_object.__name__))
|
LOG.debug("Checking if should run object {}".format(class_object.__name__))
|
||||||
try:
|
try:
|
||||||
if class_object.should_run(class_object.__name__):
|
if class_object.should_run(class_object.__name__):
|
||||||
instance = class_object()
|
objects.append(class_object)
|
||||||
objects.append(instance)
|
|
||||||
LOG.debug("Added {} to list".format(class_object.__name__))
|
LOG.debug("Added {} to list".format(class_object.__name__))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.warning("Exception {} when checking if {} should run".format(str(e), class_object.__name__))
|
LOG.warning("Exception {} when checking if {} should run".format(str(e), class_object.__name__))
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_instances(cls) -> Sequence[Type[PluginType]]:
|
||||||
|
"""
|
||||||
|
Returns the type objects from base_package_spec.
|
||||||
|
base_package name and file must refer to the same package otherwise bad results
|
||||||
|
:return: A list of parent_class objects.
|
||||||
|
"""
|
||||||
|
class_objects = cls.get_classes()
|
||||||
|
instances = []
|
||||||
|
for class_object in class_objects:
|
||||||
|
try:
|
||||||
|
instance = class_object()
|
||||||
|
instances.append(instance)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.warning("Exception {} when initializing {}".format(str(e), class_object.__name__))
|
||||||
|
return instances
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def base_package_file():
|
def base_package_file():
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import TestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class SomeDummyPlugin:
|
||||||
|
pass
|
|
@ -0,0 +1,7 @@
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import TestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class BadPluginInit(TestPlugin):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
raise Exception("TestException")
|
|
@ -0,0 +1,15 @@
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import TestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class NoInheritance:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BadInit(TestPlugin):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
raise Exception("TestException")
|
||||||
|
|
||||||
|
|
||||||
|
class ProperClass(TestPlugin):
|
||||||
|
pass
|
|
@ -0,0 +1,22 @@
|
||||||
|
from infection_monkey.utils.plugins.plugin import Plugin
|
||||||
|
import infection_monkey.utils.plugins.pluginTests
|
||||||
|
|
||||||
|
|
||||||
|
class TestPlugin(Plugin):
|
||||||
|
classes_to_load = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def should_run(class_name):
|
||||||
|
"""
|
||||||
|
Decides if post breach action is enabled in config
|
||||||
|
:return: True if it needs to be ran, false otherwise
|
||||||
|
"""
|
||||||
|
return class_name in TestPlugin.classes_to_load
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def base_package_file():
|
||||||
|
return infection_monkey.utils.plugins.pluginTests.__file__
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def base_package_name():
|
||||||
|
return infection_monkey.utils.plugins.pluginTests.__package__
|
|
@ -0,0 +1,5 @@
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import TestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class PluginWorking(TestPlugin):
|
||||||
|
pass
|
|
@ -0,0 +1,36 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.ComboFile import BadInit, ProperClass
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginWorking import PluginWorking
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.BadImport import SomeDummyPlugin
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.BadInit import BadPluginInit
|
||||||
|
from infection_monkey.utils.plugins.pluginTests.PluginTestClass import TestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class PluginTester(TestCase):
|
||||||
|
|
||||||
|
def test_combo_file(self):
|
||||||
|
TestPlugin.classes_to_load = [BadInit.__name__, ProperClass.__name__]
|
||||||
|
to_init = TestPlugin.get_classes()
|
||||||
|
self.assertEqual(len(to_init), 2)
|
||||||
|
objects = TestPlugin.get_instances()
|
||||||
|
self.assertEqual(len(objects), 1)
|
||||||
|
|
||||||
|
def test_bad_init(self):
|
||||||
|
TestPlugin.classes_to_load = [BadPluginInit.__name__]
|
||||||
|
to_init = TestPlugin.get_classes()
|
||||||
|
self.assertEqual(len(to_init), 1)
|
||||||
|
objects = TestPlugin.get_instances()
|
||||||
|
self.assertEqual(len(objects), 0)
|
||||||
|
|
||||||
|
def test_bad_import(self):
|
||||||
|
TestPlugin.classes_to_load = [SomeDummyPlugin.__name__]
|
||||||
|
to_init = TestPlugin.get_classes()
|
||||||
|
self.assertEqual(len(to_init), 0)
|
||||||
|
|
||||||
|
def test_flow(self):
|
||||||
|
TestPlugin.classes_to_load = [PluginWorking.__name__]
|
||||||
|
to_init = TestPlugin.get_classes()
|
||||||
|
self.assertEqual(len(to_init), 1)
|
||||||
|
objects = TestPlugin.get_instances()
|
||||||
|
self.assertEqual(len(objects), 1)
|
Loading…
Reference in New Issue