diff --git a/monkey/monkey_island/cc/models/monkey.py b/monkey/monkey_island/cc/models/monkey.py index 3e1e3d7c5..520b967a0 100644 --- a/monkey/monkey_island/cc/models/monkey.py +++ b/monkey/monkey_island/cc/models/monkey.py @@ -2,8 +2,8 @@ Define a Document Schema for the Monkey document. """ import mongoengine -from mongoengine import Document, StringField, ListField, BooleanField, EmbeddedDocumentField, DateField, \ - ReferenceField +from mongoengine import Document, StringField, ListField, BooleanField, EmbeddedDocumentField, ReferenceField, \ + DateTimeField from monkey_island.cc.models.monkey_ttl import MonkeyTtl @@ -24,8 +24,8 @@ class Monkey(Document): hostname = StringField() internet_access = BooleanField() ip_addresses = ListField(StringField()) - keepalive = DateField() - modifytime = DateField() + keepalive = DateTimeField() + modifytime = DateTimeField() # TODO change this to an embedded document as well - RN it's an unnamed tuple which is confusing. parent = ListField(ListField(StringField())) config_error = BooleanField() @@ -41,6 +41,10 @@ class Monkey(Document): except IndexError: raise MonkeyNotFoundError("id: {0}".format(str(db_id))) + @staticmethod + def get_latest_modifytime(): + return Monkey.objects.order_by('-modifytime').first().modifytime + def is_dead(self): monkey_is_dead = False if self.dead: diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 01990ff78..b174fc560 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,4 +1,5 @@ import logging +from monkey_island.cc.models import Monkey from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -29,7 +30,13 @@ class AttackReportService: Generates new report based on telemetries, replaces old report in db with new one. :return: Report object """ - report = {'techniques': {}, 'latest_telem_time': AttackReportService.get_latest_attack_telem_time(), 'name': REPORT_NAME} + report =\ + { + 'techniques': {}, + 'meta': {'latest_monkey_modifytime': Monkey.get_latest_modifytime()}, + 'name': REPORT_NAME + } + for tech_id, value in AttackConfig.get_technique_values().items(): if value: try: @@ -55,9 +62,10 @@ class AttackReportService: :return: report dict. """ if AttackReportService.is_report_generated(): - telem_time = AttackReportService.get_latest_attack_telem_time() + monkey_modifytime = Monkey.get_latest_modifytime() latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME}) - if telem_time and latest_report['latest_telem_time'] and telem_time == latest_report['latest_telem_time']: + report_modifytime = latest_report['meta']['latest_monkey_modifytime'] + if monkey_modifytime and report_modifytime and monkey_modifytime == report_modifytime: return latest_report return AttackReportService.generate_new_report() diff --git a/monkey/monkey_island/cc/services/node.py b/monkey/monkey_island/cc/services/node.py index 442fb391a..9da76b358 100644 --- a/monkey/monkey_island/cc/services/node.py +++ b/monkey/monkey_island/cc/services/node.py @@ -308,10 +308,6 @@ class NodeService: def is_monkey_finished_running(): return NodeService.is_any_monkey_exists() and not NodeService.is_any_monkey_alive() - @staticmethod - def get_latest_modified_monkey(): - return mongo.db.monkey.find({}).sort('modifytime', -1).limit(1) - @staticmethod def add_credentials_to_monkey(monkey_id, creds): mongo.db.monkey.update( diff --git a/monkey/monkey_island/cc/services/report.py b/monkey/monkey_island/cc/services/report.py index 2a1a58d2e..f4ce81b4f 100644 --- a/monkey/monkey_island/cc/services/report.py +++ b/monkey/monkey_island/cc/services/report.py @@ -10,6 +10,7 @@ from enum import Enum from six import text_type from monkey_island.cc.database import mongo +from monkey_island.cc.models import Monkey from monkey_island.cc.report_exporter_manager import ReportExporterManager from monkey_island.cc.services.config import ConfigService from monkey_island.cc.services.edge import EdgeService @@ -714,7 +715,7 @@ class ReportService: config_users = ReportService.get_config_users() config_passwords = ReportService.get_config_passwords() cross_segment_issues = ReportService.get_cross_segment_issues() - monkey_latest_modify_time = list(NodeService.get_latest_modified_monkey())[0]['modifytime'] + monkey_latest_modify_time = Monkey.get_latest_modifytime() report = \ { @@ -779,7 +780,7 @@ class ReportService: if latest_report_doc: report_latest_modifytime = latest_report_doc['meta']['latest_monkey_modifytime'] - latest_monkey_modifytime = NodeService.get_latest_modified_monkey()[0]['modifytime'] + latest_monkey_modifytime = Monkey.get_latest_modifytime() return report_latest_modifytime == latest_monkey_modifytime return False