forked from p15670423/monkey
Improved the monkey start function structure a bit, extracted to functions
Prep work for changing system info collection to modular system
This commit is contained in:
parent
56d601967b
commit
fb0fea6f6a
|
@ -32,11 +32,17 @@ 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
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
|
|
||||||
|
MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, shutting down"
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class PlannedShutdown(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InfectionMonkey(object):
|
class InfectionMonkey(object):
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self._keep_running = False
|
self._keep_running = False
|
||||||
|
@ -87,22 +93,18 @@ class InfectionMonkey(object):
|
||||||
LOG.debug("Default server: %s is already in command servers list" % self._default_server)
|
LOG.debug("Default server: %s is already in command servers list" % self._default_server)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
LOG.info("Monkey is running...")
|
try:
|
||||||
|
LOG.info("Monkey is starting...")
|
||||||
|
|
||||||
|
LOG.debug("Starting the setup phase.")
|
||||||
# Sets island's IP and port for monkey to communicate to
|
# Sets island's IP and port for monkey to communicate to
|
||||||
if not self.set_default_server():
|
self.set_default_server()
|
||||||
return
|
|
||||||
self.set_default_port()
|
self.set_default_port()
|
||||||
|
|
||||||
# Create a dir for monkey files if there isn't one
|
# Create a dir for monkey files if there isn't one
|
||||||
create_monkey_dir()
|
create_monkey_dir()
|
||||||
|
|
||||||
if WindowsUpgrader.should_upgrade():
|
self.upgrade_to_64_if_needed()
|
||||||
self._upgrading_to_64 = True
|
|
||||||
self._singleton.unlock()
|
|
||||||
LOG.info("32bit monkey running on 64bit Windows. Upgrading.")
|
|
||||||
WindowsUpgrader.upgrade(self._opts)
|
|
||||||
return
|
|
||||||
|
|
||||||
ControlClient.wakeup(parent=self._parent)
|
ControlClient.wakeup(parent=self._parent)
|
||||||
ControlClient.load_control_config()
|
ControlClient.load_control_config()
|
||||||
|
@ -110,9 +112,7 @@ class InfectionMonkey(object):
|
||||||
if is_windows_os():
|
if is_windows_os():
|
||||||
T1106Telem(ScanStatus.USED, UsageEnum.SINGLETON_WINAPI).send()
|
T1106Telem(ScanStatus.USED, UsageEnum.SINGLETON_WINAPI).send()
|
||||||
|
|
||||||
if not WormConfiguration.alive:
|
self.shutdown_by_not_alive_config()
|
||||||
LOG.info("Marked not alive from configuration")
|
|
||||||
return
|
|
||||||
|
|
||||||
if firewall.is_enabled():
|
if firewall.is_enabled():
|
||||||
firewall.add_firewall_rule()
|
firewall.add_firewall_rule()
|
||||||
|
@ -124,20 +124,12 @@ class InfectionMonkey(object):
|
||||||
StateTelem(is_done=False).send()
|
StateTelem(is_done=False).send()
|
||||||
TunnelTelem().send()
|
TunnelTelem().send()
|
||||||
|
|
||||||
if WormConfiguration.collect_system_info:
|
LOG.debug("Starting the post-breach phase.")
|
||||||
LOG.debug("Calling system info collection")
|
self.collect_system_info_if_configured()
|
||||||
system_info_collector = SystemInfoCollector()
|
PostBreach().execute_all_configured()
|
||||||
system_info = system_info_collector.get_info()
|
|
||||||
SystemInfoTelem(system_info).send()
|
|
||||||
|
|
||||||
# Executes post breach actions
|
LOG.debug("Starting the propagation phase.")
|
||||||
PostBreach().execute()
|
self.shutdown_by_max_depth_reached()
|
||||||
|
|
||||||
if 0 == WormConfiguration.depth:
|
|
||||||
TraceTelem("Reached max depth, shutting down").send()
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
|
|
||||||
|
|
||||||
for iteration_index in range(WormConfiguration.max_iterations):
|
for iteration_index in range(WormConfiguration.max_iterations):
|
||||||
ControlClient.keepalive()
|
ControlClient.keepalive()
|
||||||
|
@ -224,6 +216,35 @@ class InfectionMonkey(object):
|
||||||
if monkey_tunnel:
|
if monkey_tunnel:
|
||||||
monkey_tunnel.stop()
|
monkey_tunnel.stop()
|
||||||
monkey_tunnel.join()
|
monkey_tunnel.join()
|
||||||
|
except PlannedShutdown:
|
||||||
|
LOG.info("A planned shutdown of the Monkey occurred. Logging the reason and finishing execution.")
|
||||||
|
LOG.exception("Planned shutdown, reason:")
|
||||||
|
|
||||||
|
def shutdown_by_max_depth_reached(self):
|
||||||
|
if 0 == WormConfiguration.depth:
|
||||||
|
TraceTelem(MAX_DEPTH_REACHED_MESSAGE).send()
|
||||||
|
raise PlannedShutdown(MAX_DEPTH_REACHED_MESSAGE)
|
||||||
|
else:
|
||||||
|
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
|
||||||
|
|
||||||
|
def collect_system_info_if_configured(self):
|
||||||
|
if WormConfiguration.collect_system_info:
|
||||||
|
LOG.debug("Calling system info collection")
|
||||||
|
system_info_collector = SystemInfoCollector()
|
||||||
|
system_info = system_info_collector.get_info()
|
||||||
|
SystemInfoTelem(system_info).send()
|
||||||
|
|
||||||
|
def shutdown_by_not_alive_config(self):
|
||||||
|
if not WormConfiguration.alive:
|
||||||
|
raise PlannedShutdown("Marked 'not alive' from configuration.")
|
||||||
|
|
||||||
|
def upgrade_to_64_if_needed(self):
|
||||||
|
if WindowsUpgrader.should_upgrade():
|
||||||
|
self._upgrading_to_64 = True
|
||||||
|
self._singleton.unlock()
|
||||||
|
LOG.info("32bit monkey running on 64bit Windows. Upgrading.")
|
||||||
|
WindowsUpgrader.upgrade(self._opts)
|
||||||
|
raise PlannedShutdown("Finished upgrading from 32bit to 64bit.")
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
LOG.info("Monkey cleanup started")
|
LOG.info("Monkey cleanup started")
|
||||||
|
@ -346,9 +367,11 @@ class InfectionMonkey(object):
|
||||||
self._default_server_port = ''
|
self._default_server_port = ''
|
||||||
|
|
||||||
def set_default_server(self):
|
def set_default_server(self):
|
||||||
|
"""
|
||||||
|
Sets the default server for the Monkey to communicate back to.
|
||||||
|
:raises PlannedShutdown if couldn't find the server.
|
||||||
|
"""
|
||||||
if not ControlClient.find_server(default_tunnel=self._default_tunnel):
|
if not ControlClient.find_server(default_tunnel=self._default_tunnel):
|
||||||
LOG.info("Monkey couldn't find server. Going down.")
|
raise PlannedShutdown("Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel))
|
||||||
return False
|
|
||||||
self._default_server = WormConfiguration.current_server
|
self._default_server = WormConfiguration.current_server
|
||||||
LOG.debug("default server set to: %s" % self._default_server)
|
LOG.debug("default server set to: %s" % self._default_server)
|
||||||
return True
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class PostBreach(object):
|
||||||
self.os_is_linux = not is_windows_os()
|
self.os_is_linux = not is_windows_os()
|
||||||
self.pba_list = self.config_to_pba_list()
|
self.pba_list = self.config_to_pba_list()
|
||||||
|
|
||||||
def execute(self):
|
def execute_all_configured(self):
|
||||||
"""
|
"""
|
||||||
Executes all post breach actions.
|
Executes all post breach actions.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue