Merge pull request #57 from guardicore/bugfix/fix-various-exploit-bugs

Bugfix/fix various exploit bugs
This commit is contained in:
Daniel Goldberg 2017-10-09 10:43:51 +03:00 committed by GitHub
commit 930050a713
6 changed files with 36 additions and 27 deletions

View File

@ -173,6 +173,8 @@ class Configuration(object):
# addresses of internet servers to ping and check if the monkey has internet acccess. # addresses of internet servers to ping and check if the monkey has internet acccess.
internet_services = ["monkey.guardicore.com", "www.google.com"] internet_services = ["monkey.guardicore.com", "www.google.com"]
keep_tunnel_open_time = 60
########################### ###########################
# scanners config # scanners config
########################### ###########################

View File

@ -6,6 +6,7 @@
"monkey.guardicore.com", "monkey.guardicore.com",
"www.google.com" "www.google.com"
], ],
"keep_tunnel_open_time": 60,
"range_class": "RelativeRange", "range_class": "RelativeRange",
"range_fixed": [ "range_fixed": [
"" ""

View File

@ -100,7 +100,6 @@ class SambaCryExploiter(HostExploiter):
smb_client = self.connect_to_server(host.ip_addr, creds) smb_client = self.connect_to_server(host.ip_addr, creds)
self.upload_module(smb_client, host, share, depth) self.upload_module(smb_client, host, share, depth)
self.trigger_module(smb_client, share) self.trigger_module(smb_client, share)
smb_client.close()
except (impacket.smbconnection.SessionError, SessionError): except (impacket.smbconnection.SessionError, SessionError):
LOG.debug( LOG.debug(
"Exception trying to exploit host: %s, share: %s, with creds: %s." % (host.ip_addr, share, str(creds))) "Exception trying to exploit host: %s, share: %s, with creds: %s." % (host.ip_addr, share, str(creds)))
@ -125,7 +124,6 @@ class SambaCryExploiter(HostExploiter):
# Ignore exception to try and delete as much as possible # Ignore exception to try and delete as much as possible
pass pass
smb_client.disconnectTree(tree_id) smb_client.disconnectTree(tree_id)
smb_client.close()
def get_trigger_result(self, ip, share, creds): def get_trigger_result(self, ip, share, creds):
""" """
@ -147,7 +145,6 @@ class SambaCryExploiter(HostExploiter):
pass pass
smb_client.disconnectTree(tree_id) smb_client.disconnectTree(tree_id)
smb_client.close()
return file_content return file_content
def get_writable_shares_creds_dict(self, ip): def get_writable_shares_creds_dict(self, ip):
@ -159,6 +156,8 @@ class SambaCryExploiter(HostExploiter):
writable_shares_creds_dict = {} writable_shares_creds_dict = {}
credentials_list = self.get_credentials_list() credentials_list = self.get_credentials_list()
LOG.debug("SambaCry credential list: %s" % str(credentials_list))
for credentials in credentials_list: for credentials in credentials_list:
try: try:
smb_client = self.connect_to_server(ip, credentials) smb_client = self.connect_to_server(ip, credentials)
@ -169,7 +168,6 @@ class SambaCryExploiter(HostExploiter):
if self.is_share_writable(smb_client, share): if self.is_share_writable(smb_client, share):
writable_shares_creds_dict[share] = credentials writable_shares_creds_dict[share] = credentials
smb_client.close()
except (impacket.smbconnection.SessionError, SessionError): except (impacket.smbconnection.SessionError, SessionError):
# If failed using some credentials, try others. # If failed using some credentials, try others.
pass pass

View File

@ -1,17 +1,18 @@
import sys
import os
import time
import logging
import tunnel
import argparse import argparse
import logging
import os
import subprocess import subprocess
from system_singleton import SystemSingleton import sys
from network.firewall import app as firewall import time
from control import ControlClient
import tunnel
from config import WormConfiguration from config import WormConfiguration
from network.network_scanner import NetworkScanner from control import ControlClient
from model import DELAY_DELETE_CMD from model import DELAY_DELETE_CMD
from network.firewall import app as firewall
from network.network_scanner import NetworkScanner
from system_info import SystemInfoCollector from system_info import SystemInfoCollector
from system_singleton import SystemSingleton
__author__ = 'itamar' __author__ = 'itamar'
@ -80,8 +81,6 @@ class ChaosMonkey(object):
if monkey_tunnel: if monkey_tunnel:
monkey_tunnel.start() monkey_tunnel.start()
last_exploit_time = None
ControlClient.send_telemetry("state", {'done': False}) ControlClient.send_telemetry("state", {'done': False})
self._default_server = WormConfiguration.current_server self._default_server = WormConfiguration.current_server
@ -101,7 +100,7 @@ class ChaosMonkey(object):
else: else:
LOG.debug("Running with depth: %d" % WormConfiguration.depth) LOG.debug("Running with depth: %d" % WormConfiguration.depth)
for _ in xrange(WormConfiguration.max_iterations): for iteration_index in xrange(WormConfiguration.max_iterations):
ControlClient.keepalive() ControlClient.keepalive()
ControlClient.load_control_config() ControlClient.load_control_config()
@ -146,7 +145,6 @@ class ChaosMonkey(object):
LOG.debug("Skipping %r - exploitation failed before", machine) LOG.debug("Skipping %r - exploitation failed before", machine)
continue continue
if monkey_tunnel: if monkey_tunnel:
monkey_tunnel.set_tunnel_for_host(machine) monkey_tunnel.set_tunnel_for_host(machine)
if self._default_server: if self._default_server:
@ -172,15 +170,14 @@ class ChaosMonkey(object):
'exploiter': exploiter.__class__.__name__}) 'exploiter': exploiter.__class__.__name__})
except Exception as exc: except Exception as exc:
LOG.error("Exception while attacking %s using %s: %s", LOG.exception("Exception while attacking %s using %s: %s",
machine, exploiter.__class__.__name__, exc) machine, exploiter.__class__.__name__, exc)
ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__, ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
'exploiter': exploiter.__class__.__name__}) 'exploiter': exploiter.__class__.__name__})
continue continue
if successful_exploiter: if successful_exploiter:
self._exploited_machines.add(machine) self._exploited_machines.add(machine)
last_exploit_time = time.time()
ControlClient.send_telemetry('exploit', {'result': True, 'machine': machine.__dict__, ControlClient.send_telemetry('exploit', {'result': True, 'machine': machine.__dict__,
'exploiter': successful_exploiter.__class__.__name__}) 'exploiter': successful_exploiter.__class__.__name__})
@ -196,8 +193,10 @@ class ChaosMonkey(object):
else: else:
self._fail_exploitation_machines.add(machine) self._fail_exploitation_machines.add(machine)
if not is_empty: if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1):
time.sleep(WormConfiguration.timeout_between_iterations) time_to_sleep = WormConfiguration.timeout_between_iterations
LOG.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep)
time.sleep(time_to_sleep)
if self._keep_running and WormConfiguration.alive: if self._keep_running and WormConfiguration.alive:
LOG.info("Reached max iterations (%d)", WormConfiguration.max_iterations) LOG.info("Reached max iterations (%d)", WormConfiguration.max_iterations)
@ -206,8 +205,10 @@ class ChaosMonkey(object):
# if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to # if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to
# connect to the tunnel # connect to the tunnel
if last_exploit_time and (time.time() - last_exploit_time < 60): if len(self._exploited_machines) > 0:
time.sleep(time.time() - last_exploit_time) time_to_sleep = WormConfiguration.keep_tunnel_open_time
LOG.info("Sleeping %d seconds for exploited machines to connect to tunnel", time_to_sleep)
time.sleep(time_to_sleep)
if monkey_tunnel: if monkey_tunnel:
monkey_tunnel.stop() monkey_tunnel.stop()
@ -242,7 +243,7 @@ class ChaosMonkey(object):
close_fds=True, startupinfo=startupinfo) close_fds=True, startupinfo=startupinfo)
else: else:
os.remove(sys.executable) os.remove(sys.executable)
except Exception, exc: except Exception as exc:
LOG.error("Exception in self delete: %s", exc) LOG.error("Exception in self delete: %s", exc)
LOG.info("Monkey is shutting down") LOG.info("Monkey is shutting down")

View File

@ -29,6 +29,8 @@ def get_host_subnets():
for network in ipv4_nets: for network in ipv4_nets:
if 'broadcast' in network: if 'broadcast' in network:
network.pop('broadcast') network.pop('broadcast')
for attr in network:
network[attr] = network[attr].encode('utf-8').strip()
return ipv4_nets return ipv4_nets
@ -47,8 +49,7 @@ else:
def local_ips(): def local_ips():
ipv4_nets = get_host_subnets() valid_ips = [network['addr'] for network in get_host_subnets()]
valid_ips = [network['addr'] for network in ipv4_nets]
return valid_ips return valid_ips

View File

@ -277,6 +277,12 @@ SCHEMA = {
"type": "string", "type": "string",
"default": "{2384ec59-0df8-4ab9-918c-843740924a28}", "default": "{2384ec59-0df8-4ab9-918c-843740924a28}",
"description": "The name of the mutex used to determine whether the monkey is already running" "description": "The name of the mutex used to determine whether the monkey is already running"
},
"keep_tunnel_open_time": {
"title": "Keep tunnel open time",
"type": "integer",
"default": 60,
"description": "Time to keep tunnel open before going down after last exploit (in seconds)"
} }
} }
}, },