diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 6ce94451d..f34784041 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -123,11 +123,11 @@ class ControlClient(object): return {} @staticmethod - def send_telemetry(telem_catagory, data): + def send_telemetry(telem_category, data): if not WormConfiguration.current_server: return try: - telemetry = {'monkey_guid': GUID, 'telem_catagory': telem_catagory, 'data': data} + telemetry = {'monkey_guid': GUID, 'telem_category': telem_category, 'data': data} reply = requests.post("https://%s/api/telemetry" % (WormConfiguration.current_server,), data=json.dumps(telemetry), headers={'content-type': 'application/json'}, diff --git a/monkey/infection_monkey/exploit/__init__.py b/monkey/infection_monkey/exploit/__init__.py index 7353d77bc..6aa77733c 100644 --- a/monkey/infection_monkey/exploit/__init__.py +++ b/monkey/infection_monkey/exploit/__init__.py @@ -48,8 +48,20 @@ class HostExploiter(object): self._exploit_attempts.append({'result': result, 'user': user, 'password': password, 'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key}) - @abstractmethod def exploit_host(self): + self.pre_exploit() + result = self._exploit_host() + self.post_exploit() + return result + + def pre_exploit(self): + self.set_start_time() + + def post_exploit(self): + self.set_finish_time() + + @abstractmethod + def _exploit_host(self): raise NotImplementedError() def add_vuln_url(self, url): diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index f02c4f3d3..43336420c 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -31,7 +31,7 @@ class HadoopExploiter(WebRCE): def __init__(self, host): super(HadoopExploiter, self).__init__(host) - def exploit_host(self): + def _exploit_host(self): # Try to get exploitable url urls = self.build_potential_urls(self.HADOOP_PORTS) self.add_vulnerable_urls(urls, True) diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index ff9cefa60..86555f546 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -30,7 +30,7 @@ class MSSQLExploiter(HostExploiter): def __init__(self, host): super(MSSQLExploiter, self).__init__(host) - def exploit_host(self): + def _exploit_host(self): # Brute force to get connection username_passwords_pairs_list = self._config.get_exploit_user_password_pairs() cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list) diff --git a/monkey/infection_monkey/exploit/rdpgrinder.py b/monkey/infection_monkey/exploit/rdpgrinder.py index bb8db1d46..a3e24e33a 100644 --- a/monkey/infection_monkey/exploit/rdpgrinder.py +++ b/monkey/infection_monkey/exploit/rdpgrinder.py @@ -255,7 +255,7 @@ class RdpExploiter(HostExploiter): return True return False - def exploit_host(self): + def _exploit_host(self): global g_reactor is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT) diff --git a/monkey/infection_monkey/exploit/sambacry.py b/monkey/infection_monkey/exploit/sambacry.py index 7c49f51ae..7d9ed1010 100644 --- a/monkey/infection_monkey/exploit/sambacry.py +++ b/monkey/infection_monkey/exploit/sambacry.py @@ -57,7 +57,7 @@ class SambaCryExploiter(HostExploiter): def __init__(self, host): super(SambaCryExploiter, self).__init__(host) - def exploit_host(self): + def _exploit_host(self): if not self.is_vulnerable(): return False diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py index 2f6e3516f..337e0ec03 100644 --- a/monkey/infection_monkey/exploit/shellshock.py +++ b/monkey/infection_monkey/exploit/shellshock.py @@ -36,7 +36,7 @@ class ShellShockExploiter(HostExploiter): ) for _ in range(20)) self.skip_exist = self._config.skip_exploit_if_file_exist - def exploit_host(self): + def _exploit_host(self): # start by picking ports candidate_services = { service: self.host.services[service] for service in self.host.services if diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index 1b4071312..d49e66ae8 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -43,7 +43,7 @@ class SmbExploiter(HostExploiter): return self.host.os.get('type') in self._TARGET_OS_TYPE return False - def exploit_host(self): + def _exploit_host(self): src_path = get_target_monkey(self.host) if not src_path: diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index 09982876d..e8b933589 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -94,7 +94,7 @@ class SSHExploiter(HostExploiter): continue return exploited - def exploit_host(self): + def _exploit_host(self): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.WarningPolicy()) diff --git a/monkey/infection_monkey/exploit/vsftpd.py b/monkey/infection_monkey/exploit/vsftpd.py index 3f6a7c304..d60c336ca 100644 --- a/monkey/infection_monkey/exploit/vsftpd.py +++ b/monkey/infection_monkey/exploit/vsftpd.py @@ -60,7 +60,7 @@ class VSFTPDExploiter(HostExploiter): LOG.error('Failed to send payload to %s', self.host.ip_addr) return False - def exploit_host(self): + def _exploit_host(self): LOG.info("Attempting to trigger the Backdoor..") ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index ed4d595b7..8e1717f74 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -66,7 +66,7 @@ class WebRCE(HostExploiter): return exploit_config - def exploit_host(self): + def _exploit_host(self): """ Method that contains default exploitation workflow :return: True if exploited, False otherwise diff --git a/monkey/infection_monkey/exploit/win_ms08_067.py b/monkey/infection_monkey/exploit/win_ms08_067.py index d576af3cd..e1d2e5b85 100644 --- a/monkey/infection_monkey/exploit/win_ms08_067.py +++ b/monkey/infection_monkey/exploit/win_ms08_067.py @@ -92,7 +92,7 @@ class SRVSVC_Exploit(object): def get_telnet_port(self): """get_telnet_port() - + The port on which the Telnet service will listen. """ @@ -100,7 +100,7 @@ class SRVSVC_Exploit(object): def start(self): """start() -> socket - + Exploit the target machine and return a socket connected to it's listening Telnet service. """ @@ -175,7 +175,7 @@ class Ms08_067_Exploiter(HostExploiter): self.host.os.get('version') in self._windows_versions.keys() return False - def exploit_host(self): + def _exploit_host(self): src_path = get_target_monkey(self.host) if not src_path: diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index 29bc08981..feff1df70 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -23,7 +23,7 @@ class WmiExploiter(HostExploiter): super(WmiExploiter, self).__init__(host) @WmiTools.dcom_wrap - def exploit_host(self): + def _exploit_host(self): src_path = get_target_monkey(self.host) if not src_path: diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 92714c7d6..06e0f267b 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -285,9 +285,7 @@ class InfectionMonkey(object): result = False try: - exploiter.set_start_time() result = exploiter.exploit_host() - exploiter.set_finish_time() if result: self.successfully_exploited(machine, exploiter) return True diff --git a/monkey/infection_monkey/telemetry/attack/attack_telem.py b/monkey/infection_monkey/telemetry/attack/attack_telem.py index efbedcaff..893f4492a 100644 --- a/monkey/infection_monkey/telemetry/attack/attack_telem.py +++ b/monkey/infection_monkey/telemetry/attack/attack_telem.py @@ -15,7 +15,7 @@ class AttackTelem(BaseTelem): self.technique = technique self.status = status - telem_catagory = 'attack' + telem_category = 'attack' def get_data(self): return { diff --git a/monkey/infection_monkey/telemetry/attack/test_victim_host_telem.py b/monkey/infection_monkey/telemetry/attack/test_victim_host_telem.py index 6b5bbcb73..2ccab7483 100644 --- a/monkey/infection_monkey/telemetry/attack/test_victim_host_telem.py +++ b/monkey/infection_monkey/telemetry/attack/test_victim_host_telem.py @@ -13,7 +13,7 @@ class TestVictimHostTelem(TestCase): telem = VictimHostTelem(technique, status, machine) - self.assertEqual(telem.telem_catagory, 'attack') + self.assertEqual(telem.telem_category, 'attack') expected_data = { 'machine': { diff --git a/monkey/infection_monkey/telemetry/base_telem.py b/monkey/infection_monkey/telemetry/base_telem.py index eaafc6aa8..c232ab975 100644 --- a/monkey/infection_monkey/telemetry/base_telem.py +++ b/monkey/infection_monkey/telemetry/base_telem.py @@ -19,10 +19,10 @@ class BaseTelem(object): """ Sends telemetry to island """ - ControlClient.send_telemetry(self.telem_catagory, self.get_data()) + ControlClient.send_telemetry(self.telem_category, self.get_data()) @abc.abstractproperty - def telem_catagory(self): + def telem_category(self): """ :return: Telemetry type """ diff --git a/monkey/infection_monkey/transport/http.py b/monkey/infection_monkey/transport/http.py index e54445d52..0f01cf64a 100644 --- a/monkey/infection_monkey/transport/http.py +++ b/monkey/infection_monkey/transport/http.py @@ -49,7 +49,8 @@ class FileServHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): start_range += chunk if f.tell() == monkeyfs.getsize(self.filename): - self.report_download(self.client_address) + if self.report_download(self.client_address): + self.close_connection = 1 f.close() @@ -171,7 +172,8 @@ class HTTPServer(threading.Thread): LOG.info('File downloaded from (%s,%s)' % (dest[0], dest[1])) self.downloads += 1 if not self.downloads < self.max_downloads: - self.close_connection = 1 + return True + return False httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler) httpd.timeout = 0.5 # this is irrelevant? @@ -217,7 +219,8 @@ class LockedHTTPServer(threading.Thread): LOG.info('File downloaded from (%s,%s)' % (dest[0], dest[1])) self.downloads += 1 if not self.downloads < self.max_downloads: - self.close_connection = 1 + return True + return False httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler) self.lock.release() diff --git a/monkey/monkey_island/cc/resources/monkey.py b/monkey/monkey_island/cc/resources/monkey.py index 9a96abe3b..36720e465 100644 --- a/monkey/monkey_island/cc/resources/monkey.py +++ b/monkey/monkey_island/cc/resources/monkey.py @@ -95,7 +95,7 @@ class Monkey(flask_restful.Resource): parent_to_add = (monkey_json.get('guid'), None) # default values in case of manual run if parent and parent != monkey_json.get('guid'): # current parent is known exploit_telem = [x for x in - mongo.db.telemetry.find({'telem_catagory': {'$eq': 'exploit'}, 'data.result': {'$eq': True}, + mongo.db.telemetry.find({'telem_category': {'$eq': 'exploit'}, 'data.result': {'$eq': True}, 'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']}, 'monkey_guid': {'$eq': parent}})] if 1 == len(exploit_telem): @@ -104,7 +104,7 @@ class Monkey(flask_restful.Resource): parent_to_add = (parent, None) elif (not parent or parent == monkey_json.get('guid')) and 'ip_addresses' in monkey_json: exploit_telem = [x for x in - mongo.db.telemetry.find({'telem_catagory': {'$eq': 'exploit'}, 'data.result': {'$eq': True}, + mongo.db.telemetry.find({'telem_category': {'$eq': 'exploit'}, 'data.result': {'$eq': True}, 'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']}})] if 1 == len(exploit_telem): diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py index 69b6bcdd4..e69c5d6b0 100644 --- a/monkey/monkey_island/cc/resources/telemetry.py +++ b/monkey/monkey_island/cc/resources/telemetry.py @@ -26,7 +26,7 @@ class Telemetry(flask_restful.Resource): @jwt_required() def get(self, **kw): monkey_guid = request.args.get('monkey_guid') - telem_catagory = request.args.get('telem_catagory') + telem_category = request.args.get('telem_category') timestamp = request.args.get('timestamp') if "null" == timestamp: # special case to avoid ugly JS code... timestamp = None @@ -36,8 +36,8 @@ class Telemetry(flask_restful.Resource): if monkey_guid: find_filter["monkey_guid"] = {'$eq': monkey_guid} - if telem_catagory: - find_filter["telem_catagory"] = {'$eq': telem_catagory} + if telem_category: + find_filter["telem_category"] = {'$eq': telem_category} if timestamp: find_filter['timestamp'] = {'$gt': dateutil.parser.parse(timestamp)} @@ -53,11 +53,11 @@ class Telemetry(flask_restful.Resource): try: NodeService.update_monkey_modify_time(monkey["_id"]) - telem_catagory = telemetry_json.get('telem_catagory') - if telem_catagory in TELEM_PROCESS_DICT: - TELEM_PROCESS_DICT[telem_catagory](telemetry_json) + telem_category = telemetry_json.get('telem_category') + if telem_category in TELEM_PROCESS_DICT: + TELEM_PROCESS_DICT[telem_category](telemetry_json) else: - logger.info('Got unknown type of telemetry: %s' % telem_catagory) + logger.info('Got unknown type of telemetry: %s' % telem_category) except Exception as ex: logger.error("Exception caught while processing telemetry", exc_info=True) @@ -79,7 +79,7 @@ class Telemetry(flask_restful.Resource): monkey_label = telem_monkey_guid x["monkey"] = monkey_label objects.append(x) - if x['telem_catagory'] == 'system_info_collection' and 'credentials' in x['data']: + if x['telem_category'] == 'system_info_collection' and 'credentials' in x['data']: for user in x['data']['credentials']: if -1 != user.find(','): new_user = user.replace(',', '.') diff --git a/monkey/monkey_island/cc/resources/telemetry_feed.py b/monkey/monkey_island/cc/resources/telemetry_feed.py index 57a655297..b98d650c8 100644 --- a/monkey/monkey_island/cc/resources/telemetry_feed.py +++ b/monkey/monkey_island/cc/resources/telemetry_feed.py @@ -38,7 +38,7 @@ class TelemetryFeed(flask_restful.Resource): 'id': telem['_id'], 'timestamp': telem['timestamp'].strftime('%d/%m/%Y %H:%M:%S'), 'hostname': monkey.get('hostname', default_hostname) if monkey else default_hostname, - 'brief': TELEM_PROCESS_DICT[telem['telem_catagory']](telem) + 'brief': TELEM_PROCESS_DICT[telem['telem_category']](telem) } @staticmethod diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index bf219257b..35dd87676 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -44,7 +44,7 @@ class AttackReportService: Gets timestamp of latest attack telem :return: timestamp of latest attack telem """ - return [x['timestamp'] for x in mongo.db.telemetry.find({'telem_catagory': 'attack'}).sort('timestamp', -1).limit(1)][0] + return [x['timestamp'] for x in mongo.db.telemetry.find({'telem_category': 'attack'}).sort('timestamp', -1).limit(1)][0] @staticmethod def get_latest_report(): diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1197.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1197.py index 3201bb940..9a968e998 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1197.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1197.py @@ -13,7 +13,7 @@ class T1197(AttackTechnique): @staticmethod def get_report_data(): data = T1197.get_tech_base_data() - bits_results = mongo.db.telemetry.aggregate([{'$match': {'telem_catagory': 'attack', 'data.technique': T1197.tech_id}}, + bits_results = mongo.db.telemetry.aggregate([{'$match': {'telem_category': 'attack', 'data.technique': T1197.tech_id}}, {'$group': {'_id': {'ip_addr': '$data.machine.ip_addr', 'usage': '$data.usage'}, 'ip_addr': {'$first': '$data.machine.ip_addr'}, 'domain_name': {'$first': '$data.machine.domain_name'}, diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py index ed4a9a787..6e89bc6ab 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py @@ -29,7 +29,7 @@ class T1210(AttackTechnique): @staticmethod def get_scanned_services(): - results = mongo.db.telemetry.aggregate([{'$match': {'telem_catagory': 'scan'}}, + results = mongo.db.telemetry.aggregate([{'$match': {'telem_category': 'scan'}}, {'$sort': {'data.service_count': -1}}, {'$group': { '_id': {'ip_addr': '$data.machine.ip_addr'}, @@ -39,7 +39,7 @@ class T1210(AttackTechnique): @staticmethod def get_exploited_services(): - results = mongo.db.telemetry.aggregate([{'$match': {'telem_catagory': 'exploit', 'data.result': True}}, + results = mongo.db.telemetry.aggregate([{'$match': {'telem_category': 'exploit', 'data.result': True}}, {'$group': { '_id': {'ip_addr': '$data.machine.ip_addr'}, 'service': {'$first': '$data.info'}, diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py index fe2beb424..afcd67817 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -52,11 +52,11 @@ class AttackTechnique(object): Gets the status of a certain attack technique. :return: ScanStatus Enum object """ - if mongo.db.attack_results.find_one({'telem_catagory': 'attack', + if mongo.db.attack_results.find_one({'telem_category': 'attack', 'status': ScanStatus.USED.value, 'technique': cls.tech_id}): return ScanStatus.USED - elif mongo.db.attack_results.find_one({'telem_catagory': 'attack', + elif mongo.db.attack_results.find_one({'telem_category': 'attack', 'status': ScanStatus.SCANNED.value, 'technique': cls.tech_id}): return ScanStatus.SCANNED diff --git a/monkey/monkey_island/cc/services/report.py b/monkey/monkey_island/cc/services/report.py index 2cd0e82fa..2a1a58d2e 100644 --- a/monkey/monkey_island/cc/services/report.py +++ b/monkey/monkey_island/cc/services/report.py @@ -171,7 +171,7 @@ class ReportService: PASS_TYPE_DICT = {'password': 'Clear Password', 'lm_hash': 'LM hash', 'ntlm_hash': 'NTLM hash'} creds = [] for telem in mongo.db.telemetry.find( - {'telem_catagory': 'system_info_collection', 'data.credentials': {'$exists': True}}, + {'telem_category': 'system_info_collection', 'data.credentials': {'$exists': True}}, {'data.credentials': 1, 'monkey_guid': 1} ): monkey_creds = telem['data']['credentials'] @@ -199,7 +199,7 @@ class ReportService: """ creds = [] for telem in mongo.db.telemetry.find( - {'telem_catagory': 'system_info_collection', 'data.ssh_info': {'$exists': True}}, + {'telem_category': 'system_info_collection', 'data.ssh_info': {'$exists': True}}, {'data.ssh_info': 1, 'monkey_guid': 1} ): origin = NodeService.get_monkey_by_guid(telem['monkey_guid'])['hostname'] @@ -220,7 +220,7 @@ class ReportService: """ creds = [] for telem in mongo.db.telemetry.find( - {'telem_catagory': 'system_info_collection', 'data.Azure': {'$exists': True}}, + {'telem_category': 'system_info_collection', 'data.Azure': {'$exists': True}}, {'data.Azure': 1, 'monkey_guid': 1} ): azure_users = telem['data']['Azure']['usernames'] @@ -373,7 +373,7 @@ class ReportService: @staticmethod def get_exploits(): exploits = [] - for exploit in mongo.db.telemetry.find({'telem_catagory': 'exploit', 'data.result': True}): + for exploit in mongo.db.telemetry.find({'telem_category': 'exploit', 'data.result': True}): new_exploit = ReportService.process_exploit(exploit) if new_exploit not in exploits: exploits.append(new_exploit) @@ -382,7 +382,7 @@ class ReportService: @staticmethod def get_monkey_subnets(monkey_guid): network_info = mongo.db.telemetry.find_one( - {'telem_catagory': 'system_info_collection', 'monkey_guid': monkey_guid}, + {'telem_category': 'system_info_collection', 'monkey_guid': monkey_guid}, {'data.network_info.networks': 1} ) if network_info is None: @@ -540,7 +540,7 @@ class ReportService: @staticmethod def get_cross_segment_issues(): - scans = mongo.db.telemetry.find({'telem_catagory': 'scan'}, + scans = mongo.db.telemetry.find({'telem_category': 'scan'}, {'monkey_guid': 1, 'data.machine.ip_addr': 1, 'data.machine.services': 1}) cross_segment_issues = []