diff --git a/lib/cuckoo/common/abstracts.py b/lib/cuckoo/common/abstracts.py index f92105ea15c..567a53a6bd6 100644 --- a/lib/cuckoo/common/abstracts.py +++ b/lib/cuckoo/common/abstracts.py @@ -726,6 +726,7 @@ def set_path(self, analysis_path): self.network_path = os.path.join(self.analysis_path, "network") self.tlsmaster_path = os.path.join(self.analysis_path, "tlsmaster.txt") self.self_extracted = os.path.join(self.analysis_path, "selfextracted") + self.reports_path = os.path.join(self.analysis_path, "reports") def add_statistic_tmp(self, name, field, pretime): timediff = timeit.default_timer() - pretime diff --git a/lib/cuckoo/core/plugins.py b/lib/cuckoo/core/plugins.py index c4194b2afd6..24993b3e8bc 100644 --- a/lib/cuckoo/core/plugins.py +++ b/lib/cuckoo/core/plugins.py @@ -705,6 +705,9 @@ def __init__(self, task, results, reprocess=False): # remove unwanted/duplicate information from reporting for process in results["behavior"]["processes"]: + # Reprocessing and Behavior set from json file + if isinstance(process["calls"], list): + break process["calls"].begin_reporting() # required to convert object to list process["calls"] = list(process["calls"]) diff --git a/modules/processing/behavior.py b/modules/processing/behavior.py index 6c5de60d74e..014d77d778b 100644 --- a/modules/processing/behavior.py +++ b/modules/processing/behavior.py @@ -6,6 +6,7 @@ import logging import os import struct +import json from contextlib import suppress from lib.cuckoo.common.abstracts import Processing @@ -1180,31 +1181,50 @@ def run(self): """Run analysis. @return: results dict. """ - behavior = {"processes": Processes(self.logs_path, self.task, self.options).run()} - - instances = [ - Anomaly(), - ProcessTree(), - Summary(self.options), - Enhanced(), - EncryptedBuffers(), - ] - enabled_instances = [instance for instance in instances if getattr(self.options, instance.key, True)] - - if enabled_instances: - # Iterate calls and tell interested signatures about them - for process in behavior["processes"]: - for call in process["calls"]: - for instance in enabled_instances: - try: - instance.event_apicall(call, process) - except Exception: - log.exception('Failure in partial behavior "%s"', instance.key) - - for instance in instances: - try: - behavior[instance.key] = instance.run() - except Exception as e: - log.exception('Failed to run partial behavior class "%s" due to "%s"', instance.key, e) + behavior = [] + if path_exists(self.logs_path) and len(os.listdir(self.logs_path)) != 0: + behavior = {"processes": Processes(self.logs_path, self.task, self.options).run()} + + instances = [ + Anomaly(), + ProcessTree(), + Summary(self.options), + Enhanced(), + EncryptedBuffers(), + ] + enabled_instances = [instance for instance in instances if getattr(self.options, instance.key, True)] + + if enabled_instances: + # Iterate calls and tell interested signatures about them + for process in behavior["processes"]: + for call in process["calls"]: + for instance in enabled_instances: + try: + instance.event_apicall(call, process) + except Exception: + log.exception('Failure in partial behavior "%s"', instance.key) + + for instance in instances: + try: + behavior[instance.key] = instance.run() + except Exception as e: + log.exception('Failed to run partial behavior class "%s" due to "%s"', instance.key, e) + else: + log.warning('Analysis results folder does not exist at path "%s"', self.logs_path) + # load behavior from json if exist or env CAPE_REPORT variable + json_path = False + if os.environ.get("CAPE_REPORT") and path_exists(os.environ["CAPE_REPORT"]): + json_path = os.environ["CAPE_REPORT"] + elif os.path.exists(os.path.join(self.reports_path, "report.json")): + json_path = os.path.join(self.reports_path, "report.json") + + if not json_path: + return behavior + + with open(json_path) as f: + try: + behavior = json.load(f).get("behavior", []) + except Exception as e: + log.error("Behavior. Can't load json: %s", str(e)) return behavior diff --git a/web/analysis/views.py b/web/analysis/views.py index fd3c7158516..3b640266373 100644 --- a/web/analysis/views.py +++ b/web/analysis/views.py @@ -907,7 +907,7 @@ def chunk(request, task_id, pid, pagenum): else: chunk = dict(calls=[]) - if record["info"]["machine"].get("platform", "") == "linux": + if record["info"].get("machine", {}).get("platform", "") == "linux": return render(request, "analysis/strace/_chunk.html", {"chunk": chunk}) else: return render(request, "analysis/behavior/_chunk.html", {"chunk": chunk})