Beispiel #1
0
    def process_results(self):
        """Process the analysis results and generate the enabled reports."""
        results = RunProcessing(task=self.task).run()
        RunSignatures(results=results).run()
        RunReporting(task=self.task, results=results).run()

        # If the target is a file and the user enabled the option,
        # delete the original copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_original:
            if not os.path.exists(self.task.target):
                log.warning(
                    "Original file does not exist anymore: \"%s\": "
                    "File not found.", self.task.target)
            else:
                try:
                    os.remove(self.task.target)
                except OSError as e:
                    log.error(
                        "Unable to delete original file at path "
                        "\"%s\": %s", self.task.target, e)

        # If the target is a file and the user enabled the delete copy of
        # the binary option, then delete the copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_bin_copy:
            if not os.path.exists(self.binary):
                log.warning(
                    "Copy of the original file does not exist anymore: \"%s\": File not found",
                    self.binary)
            else:
                try:
                    os.remove(self.binary)
                except OSError as e:
                    log.error(
                        "Unable to delete the copy of the original file at path \"%s\": %s",
                        self.binary, e)
            # Check if the binary in the analysis directory is an invalid symlink. If it is, delete it.
            if os.path.islink(self.storage_binary) and not os.path.exists(
                    self.storage_binary):
                try:
                    os.remove(self.storage_binary)
                except OSError as e:
                    log.error(
                        "Unable to delete symlink to the binary copy at path \"%s\": %s",
                        self.storage_binary, e)

        log.info("Task #%d: reports generation completed (path=%s)",
                 self.task.id, self.storage)

        return True
Beispiel #2
0
def process(task_id, target=None, copy_path=None, report=False, auto=False):
    assert isinstance(task_id, int)
    results = RunProcessing(task_id=task_id).run()
    RunSignatures(task_id=task_id, results=results).run()

    if report:
        RunReporting(task_id=task_id, results=results).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)
Beispiel #3
0
    def process_results(self):
        """Process the analysis results and generate the enabled reports."""
        # This is the results container. It's what will be used by all the
        # reporting modules to make it consumable by humans and machines.
        # It will contain all the results generated by every processing
        # module available. Its structure can be observed through the JSON
        # dump in the analysis' reports folder. (If jsondump is enabled.)
        results = {}
        GetFeeds(results=results).run()
        RunProcessing(task_id=self.task.id, results=results).run()
        RunSignatures(task_id=self.task.id, results=results).run()

        try:
            log.info("Task #%d: start to generate report" % self.task.id)
            report_result = generate_result(self.task, results)
            RunReporting(task_id=self.task.id, results=report_result).run()
            Database().set_status(self.task.id, TASK_REPORTED)
        except Exception as e:
            log.error("#%s generate report failed, msg:%s" % (self.task.id, e))
            self.db.set_status(self.task.id, TASK_FAILED_REPORTING)

        # If the target is a file and the user enabled the option,
        # delete the original copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_original and self.task.id > 0:
            if not os.path.exists(self.task.target):
                log.warning("Original file does not exist anymore: \"%s\": "
                            "File not found.", self.task.target)
            else:
                try:
                    os.remove(self.task.target)
                except OSError as e:
                    log.error("Unable to delete original file at path "
                              "\"%s\": %s", self.task.target, e)

        # If the target is a file and the user enabled the delete copy of
        # the binary option, then delete the copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_bin_copy and self.task > 0:
            if not os.path.exists(self.binary):
                log.warning("Copy of the original file does not exist anymore: \"%s\": File not found", self.binary)
            else:
                try:
                    os.remove(self.binary)
                except OSError as e:
                    log.error("Unable to delete the copy of the original file at path \"%s\": %s", self.binary, e)

        log.info("Task #%d: reports generation completed (path=%s)", self.task.id, self.storage)

        return True
Beispiel #4
0
    def process_results(self):
        """Process the analysis results and generate the enabled reports."""
        # This is the results container. It's what will be used by all the
        # reporting modules to make it consumable by humans and machines.
        # It will contain all the results generated by every processing
        # module available. Its structure can be observed through the JSON
        # dump in the analysis' reports folder. (If jsondump is enabled.)
        results = { }
        results["statistics"] = { }
        results["statistics"]["processing"] = list()
        results["statistics"]["signatures"] = list()
        results["statistics"]["reporting"] = list()
        GetFeeds(results=results).run()
        RunProcessing(task=self.task.to_dict(), results=results).run()
        RunSignatures(task=self.task.to_dict(), results=results).run()
        RunReporting(task=self.task.to_dict(), results=results).run()

        # If the target is a file and the user enabled the option,
        # delete the original copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_original:
            if not os.path.exists(self.task.target):
                log.warning("Original file does not exist anymore: \"%s\": "
                            "File not found.", self.task.target)
            else:
                try:
                    os.remove(self.task.target)
                except OSError as e:
                    log.error("Unable to delete original file at path "
                              "\"%s\": %s", self.task.target, e)

        # If the target is a file and the user enabled the delete copy of
        # the binary option, then delete the copy.
        if self.task.category == "file" and self.cfg.cuckoo.delete_bin_copy:
            if not os.path.exists(self.binary):
                log.warning("Copy of the original file does not exist anymore: \"%s\": File not found", self.binary)
            else:
                try:
                    os.remove(self.binary)
                except OSError as e:
                    log.error("Unable to delete the copy of the original file at path \"%s\": %s", self.binary, e)

        log.info("Task #%d: reports generation completed (path=%s)",
                 self.task.id, self.storage)

        return True
def process(task_id, target=None, copy_path=None, report=False, auto=False):
    assert isinstance(task_id, int)
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    results = {}
    GetFeeds(results=results).run()
    RunProcessing(task_id=task_id, results=results).run()
    RunSignatures(task_id=task_id, results=results).run()

    if report:
        RunReporting(task_id=task_id, results=results).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)
Beispiel #6
0
def process(target=None, copy_path=None, task=None, report=False, auto=False):
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    results = {}
    results["statistics"] = {}
    results["statistics"]["processing"] = list()
    results["statistics"]["signatures"] = list()
    results["statistics"]["reporting"] = list()
    GetFeeds(results=results).run()
    RunProcessing(task=task, results=results).run()
    RunSignatures(task=task, results=results).run()
    task_id = task["id"]
    if report:
        if repconf.mongodb.enabled:
            host = repconf.mongodb.host
            port = repconf.mongodb.port
            db = repconf.mongodb.db
            conn = MongoClient(host, port)
            mdata = conn[db]
            analyses = mdata.analysis.find({"info.id": int(task_id)})
            if analyses.count() > 0:
                log.debug("Deleting analysis data for Task %s" % task_id)
                for analysis in analyses:
                    for process in analysis["behavior"]["processes"]:
                        for call in process["calls"]:
                            mdata.calls.remove({"_id": ObjectId(call)})
                    mdata.analysis.remove({"_id": ObjectId(analysis["_id"])})
            conn.close()
            log.debug("Deleted previous MongoDB data for Task %s" % task_id)

        if repconf.elasticsearchdb.enabled and not repconf.elasticsearchdb.searchonly:
            analyses = es.search(index=fullidx,
                                 doc_type="analysis",
                                 q="info.id: \"%s\"" % task_id)["hits"]["hits"]
            if analyses:
                for analysis in analyses:
                    esidx = analysis["_index"]
                    esid = analysis["_id"]
                    # Check if behavior exists
                    if analysis["_source"]["behavior"]:
                        for process in analysis["_source"]["behavior"][
                                "processes"]:
                            for call in process["calls"]:
                                es.delete(
                                    index=esidx,
                                    doc_type="calls",
                                    id=call,
                                )
                    # Delete the analysis results
                    es.delete(
                        index=esidx,
                        doc_type="analysis",
                        id=esid,
                    )

        RunReporting(task=task, results=results).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)
Beispiel #7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "id",
        type=str,
        help=
        "ID of the analysis to process (auto for continuous processing of unprocessed tasks)."
    )
    parser.add_argument("-c",
                        "--caperesubmit",
                        help="Allow CAPE resubmit processing.",
                        action="store_true",
                        required=False)
    parser.add_argument("-d",
                        "--debug",
                        help="Display debug messages",
                        action="store_true",
                        required=False)
    parser.add_argument("-r",
                        "--report",
                        help="Re-generate report",
                        action="store_true",
                        required=False)
    parser.add_argument("-s",
                        "--signatures",
                        help="Re-execute signatures on the report",
                        action="store_true",
                        required=False)
    parser.add_argument(
        "-p",
        "--parallel",
        help="Number of parallel threads to use (auto mode only).",
        type=int,
        required=False,
        default=1)
    parser.add_argument("-fp",
                        "--failed-processing",
                        help="reprocess failed processing",
                        action="store_true",
                        required=False,
                        default=False)
    args = parser.parse_args()

    init_yara()
    init_modules()

    if args.id == "auto":
        init_logging(auto=True, debug=args.debug)
        autoprocess(parallel=args.parallel,
                    failed_processing=args.failed_processing)
    else:
        if not os.path.exists(
                os.path.join(CUCKOO_ROOT, "storage", "analyses", args.id)):
            sys.exit(red("\n[-] Analysis folder doesn't exist anymore\n"))
        init_logging(tid=args.id, debug=args.debug)
        task = Database().view_task(int(args.id))
        if args.signatures:
            report = os.path.join(CUCKOO_ROOT, "storage", "analyses", args.id,
                                  "reports", "report.json")
            if not os.path.exists(report):
                sys.exit("File {} doest exist".format(report))

            results = json.load(open(report))
            if results is not None:
                RunSignatures(task=task.to_dict(), results=results).run()
        else:
            process(task=task, report=args.report, capeproc=args.caperesubmit)
Beispiel #8
0
def process(target=None,
            copy_path=None,
            task=None,
            report=False,
            auto=False,
            capeproc=False,
            memory_debugging=False):
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    task_dict = task.to_dict() or {}
    task_id = task_dict.get("id") or 0
    results = {
        "statistics": {
            "processing": [],
            "signatures": [],
            "reporting": []
        }
    }
    if memory_debugging:
        gc.collect()
        log.info("[%s] (1) GC object counts: %d, %d", task_id,
                 len(gc.get_objects()), len(gc.garbage))
    if memory_debugging:
        gc.collect()
        log.info("[%s] (2) GC object counts: %d, %d", task_id,
                 len(gc.get_objects()), len(gc.garbage))
    RunProcessing(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("[%s] (3) GC object counts: %d, %d", task_id,
                 len(gc.get_objects()), len(gc.garbage))

    RunSignatures(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("[%s] (4) GC object counts: %d, %d", task_id,
                 len(gc.get_objects()), len(gc.garbage))

    if report:
        if repconf.mongodb.enabled:
            host = repconf.mongodb.host
            port = repconf.mongodb.port
            db = repconf.mongodb.db
            conn = MongoClient(host,
                               port=port,
                               username=repconf.mongodb.get("username", None),
                               password=repconf.mongodb.get("password", None),
                               authSource=db)
            mdata = conn[db]
            analyses = mdata.analysis.find({"info.id": int(task_id)})
            if analyses.count() > 0:
                log.debug("Deleting analysis data for Task %s" % task_id)
                for analysis in analyses:
                    for process in analysis["behavior"].get("processes", []):
                        for call in process["calls"]:
                            mdata.calls.remove({"_id": ObjectId(call)})
                    mdata.analysis.remove({"_id": ObjectId(analysis["_id"])})
            conn.close()
            log.debug("Deleted previous MongoDB data for Task %s" % task_id)

        if repconf.elasticsearchdb.enabled and not repconf.elasticsearchdb.searchonly:
            analyses = es.search(index=fullidx,
                                 doc_type="analysis",
                                 q="info.id: \"%s\"" % task_id)["hits"]["hits"]
            if analyses:
                for analysis in analyses:
                    esidx = analysis["_index"]
                    esid = analysis["_id"]
                    # Check if behavior exists
                    if analysis["_source"]["behavior"]:
                        for process in analysis["_source"]["behavior"][
                                "processes"]:
                            for call in process["calls"]:
                                es.delete(
                                    index=esidx,
                                    doc_type="calls",
                                    id=call,
                                )
                    # Delete the analysis results
                    es.delete(
                        index=esidx,
                        doc_type="analysis",
                        id=esid,
                    )
        if auto or capeproc:
            reprocess = False
        else:
            reprocess = report

        RunReporting(task=task.to_dict(), results=results,
                     reprocess=reprocess).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)

    if memory_debugging:
        gc.collect()
        log.info("[%s] (5) GC object counts: %d, %d", task_id,
                 len(gc.get_objects()), len(gc.garbage))
        for i, obj in enumerate(gc.garbage):
            log.info("[%s] (garbage) GC object #%d: type=%s", task_id, i,
                     type(obj).__name__)
Beispiel #9
0
def process(task_id, target=None, copy_path=None, report=False, auto=False):
    assert isinstance(task_id, int)
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    results = {}
    db = Database()
    if os.path.exists(
            os.path.join(REPORT_ROOT, "storage", "analyses", str(task_id),
                         "logs")):
        GetFeeds(results=results).run()
        RunProcessing(task_id=task_id, results=results).run()
        RunSignatures(task_id=task_id, results=results).run()
    if report:
        try:
            task = db.view_task(task_id)
            results = generate_result(task, results)
            RunReporting(task_id=task_id, results=results).run()
            db.set_status(task_id, TASK_REPORTED)
        except Exception as e:
            log.error("Task #%d: reports generation failed: %s", task_id, e)
            db.set_status(task_id, TASK_FAILED_REPORTING)
        finally:
            del results

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)

        if task_id < 0 and task.mode < 2:
            json_reports = []
            targets = []
            started = []
            completed = []
            sub_tasks = db.list_subtasks(task_id)
            for sub_task in sub_tasks:
                if sub_task.status not in [
                        TASK_REPORTED, TASK_FAILED_REPORTING,
                        TASK_FAILED_ANALYSIS, TASK_FAILED_PROCESSING
                ]:
                    return

                json_path = path.join(REPORT_ROOT, "storage", "analyses",
                                      str(sub_task.id), "reports",
                                      "report.json")
                if path.exists(json_path):
                    json_report = json.load(open(json_path))
                    json_reports.append(json_report)
                    targets.append(sub_task.target)
                started.append(sub_task.started_on)
                completed.append(sub_task.completed_on)

            scores = [report["scores"] for report in json_reports]
            # get the highest scores report
            base_report = json_reports[scores.index(max(scores))]
            base_assessment_result = {
                "scores": base_report["scores"],
                "severity": base_report["severity"],
                "summary": base_report["summary"],
                "details": base_report["details"],
                "description": base_report["description"]
            }

            # get parent_task details
            parent_task = db.view_parent_task(task_id)
            log.debug(
                "#%d: sub tasks reported, start to generate the final report."
                % parent_task.id)

            # get parent_task start and complete time
            started = min(started)
            completed = max(completed)
            db.set_time(parent_task.id, "started_on", started)
            db.set_time(parent_task.id, "completed_on", completed)
            duration = (completed - started).seconds

            targetdetail = {}
            if os.path.exists(parent_task.target):
                filedetail = File(parent_task.target).get_all()
                fmt_file = pd_fmt_file(parent_task.target.encode("utf-8"))
                targetdetail = {
                    "target": filedetail["name"],
                    "size": filedetail["size"],
                    "extnomatch": 1 - fmt_file[1],
                    "type": fmt_file[2],
                    "md5": filedetail["md5"],
                    "sha1": filedetail["sha1"]
                }
            report_result = {
                "category": parent_task.category,
                "targetdetail": targetdetail,
                "reporttime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "duration": duration,
                "started": started.strftime("%Y-%m-%d %H:%M:%S"),
                "ended": completed.strftime("%Y-%m-%d %H:%M:%S"),
            }

            report_result.update(base_assessment_result)
            report_result["file_reports"] = json_reports

            try:
                reports_path = os.path.join(REPORT_ROOT, "storage", "analyses",
                                            str(parent_task.id), "reports")
                if not os.path.exists(reports_path):
                    os.makedirs(reports_path)
                RunReporting(task_id=parent_task.id,
                             results=report_result).run()
                db.set_status(parent_task.id, TASK_REPORTED)
                log.info("Task #%d: reports generation completed (path=%s)",
                         parent_task.id, reports_path)
            except Exception as e:
                log.error("#%s generate report failed, msg:%s" %
                          (parent_task.id, e))
                db.set_status(parent_task.id, TASK_FAILED_REPORTING)
            finally:
                del report_result

            # remove uncompressed dir and delete all sub tasks and their storage if they exist
            _tail = "_z1p2d1r"
            uncompressed_dir = parent_task.target + _tail
            if path.exists(uncompressed_dir):
                shutil.rmtree(uncompressed_dir, ignore_errors=True)

            try:
                for sub_task in sub_tasks:
                    db.delete_task(sub_task.id)
                    db.delete_result(sub_task.id)
                    db.delete_sub_task(sub_task.id)
                    task_path = path.join(REPORT_ROOT, "storage", "analyses",
                                          str(sub_task.id))
                    if path.exists(task_path):
                        shutil.rmtree(task_path, True)
                log.info("Delete submitted tasks successfully")
            except Exception as e:
                log.info("Delete submitted tasks failed, msg: %s" % e)

        if task_id < 0 and task.mode == 2:
            json_reports = []
            targets = []
            report_path = []
            sub_tasks = db.list_subtasks(task_id)
            for sub_task in sub_tasks:
                if sub_task.status not in [
                        TASK_REPORTED, TASK_FAILED_REPORTING,
                        TASK_FAILED_ANALYSIS, TASK_FAILED_PROCESSING
                ]:
                    return

                json_path = path.join(REPORT_ROOT, "storage", "analyses",
                                      str(sub_task.id), "reports",
                                      "report.json")
                if path.exists(json_path):
                    json_report = json.load(open(json_path))
                    json_reports.append(json_report)
                    targets.append(sub_task.target)
                    report_path.append(
                        path.join(REPORT_ROOT, "storage", "analyses",
                                  str(sub_task.id)))
            max_malscore_index = max(enumerate(json_reports),
                                     key=lambda x: x[1]["scores"])[0]
            parent_task = db.view_parent_task(task_id)
            db.set_time(parent_task.id, "started_on",
                        json_reports[max_malscore_index]["started"])
            db.set_time(parent_task.id, "completed_on",
                        json_reports[max_malscore_index]["completed"])
            reports_path = path.join(REPORT_ROOT, "storage", "analyses",
                                     str(parent_task.id))
            if not path.exists(reports_path):
                shutil.copytree(report_path[max_malscore_index], reports_path)
                db.set_status(parent_task.id, TASK_REPORTED)
                log.info("Task #%d: reports generation completed (path=%s)",
                         parent_task.id, reports_path)
            try:
                for sub_task in sub_tasks:
                    # TODO: delete negative task of mode==2
                    db.delete_task(sub_task.id)
                    db.delete_result(sub_task.id)
                    db.delete_sub_task(sub_task.id)
                    task_path = path.join(REPORT_ROOT, "storage", "analyses",
                                          str(sub_task.id))
                    if path.exists(task_path):
                        shutil.rmtree(task_path, True)
                log.info("Delete submitted tasks successfully")
            except Exception as e:
                log.info("Delete submitted tasks failed, msg: %s" % e)

    gc.collect()
Beispiel #10
0
def process(target=None, copy_path=None, task=None, report=False, auto=False, capeproc=False, memory_debugging=False):
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    task_dict = task.to_dict() or {}
    task_id = task_dict.get("id") or 0
    results = {"statistics": {"processing": [], "signatures": [], "reporting": []}}
    if memory_debugging:
        gc.collect()
        log.info("[%s] (1) GC object counts: %d, %d", task_id, len(gc.get_objects()), len(gc.garbage))
    if memory_debugging:
        gc.collect()
        log.info("[%s] (2) GC object counts: %d, %d", task_id, len(gc.get_objects()), len(gc.garbage))
    RunProcessing(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("[%s] (3) GC object counts: %d, %d", task_id, len(gc.get_objects()), len(gc.garbage))

    RunSignatures(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("[%s] (4) GC object counts: %d, %d", task_id, len(gc.get_objects()), len(gc.garbage))

    if report:
        if repconf.mongodb.enabled:
            conn, mdata, analyses = _load_mongo_report(task_id)
            if analyses:
                log.debug("Deleting analysis data for Task %s" % task_id)
                for analysis in analyses:
                    for process in analysis.get("behavior", {}).get("processes", []):
                        calls = []
                        for call in process["calls"]:
                            calls.append(ObjectId(call))
                        mdata.calls.delete_many({"_id": {"$in": calls}})
                    mdata.analysis.delete_one({"_id": ObjectId(analysis["_id"])})
            conn.close()
            log.debug("Deleted previous MongoDB data for Task %s" % task_id)

        if repconf.elasticsearchdb.enabled and not repconf.elasticsearchdb.searchonly:
            try:
                analyses = es.search(
                    index=get_analysis_index(), query=get_query_by_info_id(task_id)
                )["hits"]["hits"]
                if analyses:
                    for analysis in analyses:
                        delete_analysis_and_related_calls(analysis["_id"])
            except ESRequestError as e:
                print(e)

        if auto or capeproc:
            reprocess = False
        else:
            reprocess = report

        RunReporting(task=task.to_dict(), results=results, reprocess=reprocess).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if copy_path is not None and cfg.cuckoo.delete_bin_copy and os.path.exists(copy_path):
                os.unlink(copy_path)

    if memory_debugging:
        gc.collect()
        log.info("[%s] (5) GC object counts: %d, %d", task_id, len(gc.get_objects()), len(gc.garbage))
        for i, obj in enumerate(gc.garbage):
            log.info("[%s] (garbage) GC object #%d: type=%s", task_id, i, type(obj).__name__)
Beispiel #11
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("id", type=str, help="ID of the analysis to process (auto for continuous processing of unprocessed tasks).")
    parser.add_argument("-c", "--caperesubmit", help="Allow CAPE resubmit processing.", action="store_true", required=False)
    parser.add_argument("-d", "--debug", help="Display debug messages", action="store_true", required=False)
    parser.add_argument("-r", "--report", help="Re-generate report", action="store_true", required=False)
    parser.add_argument(
        "-p", "--parallel", help="Number of parallel threads to use (auto mode only).", type=int, required=False, default=1
    )
    parser.add_argument(
        "-fp", "--failed-processing", help="reprocess failed processing", action="store_true", required=False, default=False
    )
    parser.add_argument(
        "-mc", "--maxtasksperchild", help="Max children tasks per worker", action="store", type=int, required=False, default=7
    )
    parser.add_argument(
        "-md",
        "--memory-debugging",
        help="Enable logging garbage collection related info",
        action="store_true",
        required=False,
        default=False,
    )
    parser.add_argument(
        "-pt",
        "--processing-timeout",
        help="Max amount of time spent in processing before we fail a task",
        action="store",
        type=int,
        required=False,
        default=300,
    )
    testing_args = parser.add_argument_group("Signature testing options")
    testing_args.add_argument(
        "-sig",
        "--signatures",
        help="Re-execute signatures on the report, doesn't work for signature with self.get_raw_argument, use self.get_argument",
        action="store_true",
        default=False,
        required=False,
    )
    testing_args.add_argument(
        "-sn",
        "--signature-name",
        help="Run only one signature. To be used with --signature. Example -sig -sn cape_detected_threat",
        action="store",
        default=False,
        required=False,
    )
    testing_args.add_argument(
        "-jr",
        "--json-report",
        help="Path to json report, only if data not in mongo/default report location",
        action="store",
        default=False,
        required=False,
    )
    args = parser.parse_args()

    init_yara()
    init_modules()
    if args.id == "auto":
        init_logging(auto=True, debug=args.debug)
        autoprocess(
            parallel=args.parallel,
            failed_processing=args.failed_processing,
            maxtasksperchild=args.maxtasksperchild,
            memory_debugging=args.memory_debugging,
            processing_timeout=args.processing_timeout,
        )
    else:
        if not os.path.exists(os.path.join(CUCKOO_ROOT, "storage", "analyses", args.id)):
            sys.exit(red("\n[-] Analysis folder doesn't exist anymore\n"))
        init_logging(tid=args.id, debug=args.debug)
        task = Database().view_task(int(args.id))
        if args.signatures:
            conn = False
            report = False
            # check mongo
            if repconf.mongodb.enabled:
                conn, _, results = _load_mongo_report(int(args.id), return_one=True)
            if not results:
                # fallback to json
                report = os.path.join(CUCKOO_ROOT, "storage", "analyses", args.id, "reports", "report.json")
                if not os.path.exists(report):
                    if args.json_report and not os.path.exists(args.json_report):
                        report = args.json_report
                    else:
                        sys.exit("File {} doest exist".format(report))
                if report:
                    results = json.load(open(report))
            if results is not None:
                RunSignatures(task=task.to_dict(), results=results).run(args.signature_name)
        else:
            process(task=task, report=args.report, capeproc=args.caperesubmit, memory_debugging=args.memory_debugging)
Beispiel #12
0
def process(target=None,
            copy_path=None,
            task=None,
            report=False,
            auto=False,
            capeproc=False,
            memory_debugging=False):
    # This is the results container. It's what will be used by all the
    # reporting modules to make it consumable by humans and machines.
    # It will contain all the results generated by every processing
    # module available. Its structure can be observed through the JSON
    # dump in the analysis' reports folder. (If jsondump is enabled.)
    task_dict = task.to_dict() or {}
    task_id = task_dict.get("id") or 0
    set_formatter_fmt(task_id)
    results = {
        "statistics": {
            "processing": [],
            "signatures": [],
            "reporting": []
        }
    }
    if memory_debugging:
        gc.collect()
        log.info("(1) GC object counts: %d, %d", len(gc.get_objects()),
                 len(gc.garbage))
    if memory_debugging:
        gc.collect()
        log.info("(2) GC object counts: %d, %d", len(gc.get_objects()),
                 len(gc.garbage))
    RunProcessing(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("(3) GC object counts: %d, %d", len(gc.get_objects()),
                 len(gc.garbage))

    RunSignatures(task=task_dict, results=results).run()
    if memory_debugging:
        gc.collect()
        log.info("(4) GC object counts: %d, %d", len(gc.get_objects()),
                 len(gc.garbage))

    if report:
        if auto or capeproc:
            reprocess = False
        else:
            reprocess = report

        RunReporting(task=task.to_dict(), results=results,
                     reprocess=reprocess).run()
        Database().set_status(task_id, TASK_REPORTED)

        if auto:
            if cfg.cuckoo.delete_original and os.path.exists(target):
                os.unlink(target)

            if copy_path is not None and cfg.cuckoo.delete_bin_copy and os.path.exists(
                    copy_path):
                os.unlink(copy_path)

    if memory_debugging:
        gc.collect()
        log.info("(5) GC object counts: %d, %d", len(gc.get_objects()),
                 len(gc.garbage))
        for i, obj in enumerate(gc.garbage):
            log.info("(garbage) GC object #%d: type=%s", i, type(obj).__name__)