forked from p34709852/monkey
Merge pull request #57 from guardicore/bugfix/fix-various-exploit-bugs
Bugfix/fix various exploit bugs
This commit is contained in:
commit
930050a713
|
@ -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
|
||||||
###########################
|
###########################
|
||||||
|
|
|
@ -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": [
|
||||||
""
|
""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue