コード例 #1
0
def vt_scan_file(api_key, md5, job_id, additional_config_params):
    try:
        binary = general.get_binary(job_id)
    except Exception:
        raise AnalyzerRunException(
            "couldn't retrieve the binary to perform a scan")

    headers = {'x-apikey': api_key}
    files = {'file': binary}
    uri = 'files'

    try:
        response = requests.post(vt_base + uri, files=files, headers=headers)
        response.raise_for_status()
    except requests.RequestException as e:
        raise AnalyzerRunException(e)
    result = response.json()
    # pprint.pprint(result)

    result_data = result.get('data', {})
    scan_id = result_data.get('id', '')
    if not scan_id:
        raise AnalyzerRunException(
            "no scan_id given by VirusTotal to retrieve the results")
    # max 5 minutes waiting
    max_tries = additional_config_params.get('max_tries', 100)
    poll_distance = 5
    got_result = False
    uri = "analyses/{}".format(scan_id)
    for chance in range(max_tries):
        time.sleep(poll_distance)
        logger.info(
            "vt polling, try n.{}. job_id {}. starting the query".format(
                chance + 1, job_id))
        try:
            response = requests.get(vt_base + uri, headers=headers)
            response.raise_for_status()
        except requests.RequestException as e:
            raise AnalyzerRunException(e)
        json_response = response.json()
        # pprint.pprint(json_response)
        analysis_status = json_response.get('data',
                                            {}).get('attributes',
                                                    {}).get('status', '')
        if analysis_status == "completed":
            got_result = True
            break
        else:
            logger.info("vt polling, try n.{}. job_id {}. status:{}".format(
                chance + 1, job_id, analysis_status))

    if not got_result:
        raise AnalyzerRunException(
            "max VT polls tried without getting any result. job_id {}".format(
                job_id))

    # retrieve the FULL report, not only scans results. If it's a new sample, it's free of charge
    result = vt3_get.vt_get_report(api_key, md5, "hash", {}, job_id)
    # pprint.pprint(result)
    return result
コード例 #2
0
ファイル: cuckoo_scan.py プロジェクト: ninoseki/IntelOwl
def run(analyzer_name, job_id, filepath, filename, md5,
        additional_config_params):
    logger.info("started analyzer {} job_id {}"
                "".format(analyzer_name, job_id))
    report = general.get_basic_report_template(analyzer_name)
    try:
        # cuckoo installation can be with or without the api_token
        # it depends on version and configuration
        api_key_name = additional_config_params.get("api_key_name", "")
        if api_key_name:
            api_key = secrets.get_secret(api_key_name)
        else:
            api_key = None
            logger.info("job_id {} md5 {} analyzer {} no API key set"
                        "".format(job_id, md5, analyzer_name))

        cuckoo_url = secrets.get_secret("CUCKOO_URL")
        if not cuckoo_url:
            raise AnalyzerRunException("cuckoo URL missing")

        cuckoo_analysis = CuckooAnalysis(api_key, cuckoo_url)

        binary = general.get_binary(job_id)
        if not binary:
            raise AnalyzerRunException("is the binary empty?!")
        _cuckoo_scan_file(cuckoo_analysis, additional_config_params, filename,
                          md5, binary)

        result = cuckoo_analysis.report
        # pprint.pprint(result)
        report["report"] = result
    except AnalyzerRunException as e:
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.error(error_message)
        report["errors"].append(error_message)
        report["success"] = False
    except Exception as e:
        traceback.print_exc()
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.exception(error_message)
        report["errors"].append(str(e))
        report["success"] = False
    else:
        report["success"] = True

    general.set_report_and_cleanup(job_id, report)

    logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id))

    return report
コード例 #3
0
ファイル: intezer_scan.py プロジェクト: ninoseki/IntelOwl
def run(analyzer_name, job_id, filepath, filename, md5,
        additional_config_params):
    logger.info("started analyzer {} job_id {}"
                "".format(analyzer_name, job_id))
    report = general.get_basic_report_template(analyzer_name)
    try:
        api_key_name = additional_config_params.get("api_key_name", "")
        if not api_key_name:
            api_key_name = "INTEZER_KEY"
        api_key = secrets.get_secret(api_key_name)
        if not api_key:
            raise AnalyzerRunException("no api key retrieved")

        intezer_token = os.environ.get("INTEZER_TOKEN", "")
        intezer_token_date = os.environ.get("INTEZER_TOKEN_DATE", "")
        today = get_now_date_only()
        if not intezer_token or intezer_token_date != today:
            intezer_token = _get_access_token(api_key)
            if not intezer_token:
                raise AnalyzerRunException("token extraction failed")

        binary = general.get_binary(job_id)
        result = _intezer_scan_file(intezer_token, md5, filename, binary,
                                    additional_config_params)

        # pprint.pprint(result)
        report["report"] = result
    except AnalyzerRunException as e:
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.error(error_message)
        report["errors"].append(error_message)
        report["success"] = False
    except Exception as e:
        traceback.print_exc()
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.exception(error_message)
        report["errors"].append(str(e))
        report["success"] = False
    else:
        report["success"] = True

    general.set_report_and_cleanup(job_id, report)

    logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id))

    return report
コード例 #4
0
ファイル: file_info.py プロジェクト: ninoseki/IntelOwl
def run(analyzer_name, job_id, filepath, filename, md5,
        additional_config_params):
    logger.info("started analyzer {} job_id {}"
                "".format(analyzer_name, job_id))
    report = general.get_basic_report_template(analyzer_name)
    try:
        results = {}
        results["magic"] = magic.from_file(filepath)
        results["mimetype"] = magic.from_file(filepath, mime=True)
        results["filetype"] = pyexifinfo.fileType(filepath)

        exif_report = pyexifinfo.get_json(filepath)
        if exif_report:
            exif_report_cleaned = {
                key: value
                for key, value in exif_report[0].items()
                if not (key.startswith("File") or key.startswith("SourceFile"))
            }
            results["exiftool"] = exif_report_cleaned

        binary = general.get_binary(job_id)
        results["md5"] = hashlib.md5(binary).hexdigest()
        results["sha1"] = hashlib.sha1(binary).hexdigest()
        results["sha256"] = hashlib.sha256(binary).hexdigest()
        results["ssdeep"] = pydeep.hash_file(filepath).decode()

        report["report"] = results
    except AnalyzerRunException as e:
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.error(error_message)
        report["errors"].append(error_message)
        report["success"] = False
    except Exception as e:
        traceback.print_exc()
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.exception(error_message)
        report["errors"].append(str(e))
        report["success"] = False
    else:
        report["success"] = True

    general.set_report_and_cleanup(job_id, report)

    logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id))

    return report
コード例 #5
0
def run(analyzer_name, job_id, filepath, filename, md5,
        additional_config_params):
    logger.info("started analyzer {} job_id {}"
                "".format(analyzer_name, job_id))
    report = general.get_basic_report_template(analyzer_name)
    try:
        api_key_name = additional_config_params.get('api_key_name', '')
        if not api_key_name:
            api_key_name = "VT_KEY"
        api_key = secrets.get_secret(api_key_name)
        if not api_key:
            raise AnalyzerRunException("no api key retrieved")

        # this is a config value that can be used to force the waiting of the scan result anyway
        wait_for_scan_anyway = additional_config_params.get(
            'wait_for_scan_anyway', False)

        notify_url = secrets.get_secret("VT_NOTIFY_URL")

        binary = general.get_binary(job_id, logger)
        result = _vt_scan_file(api_key, notify_url, binary)

        # in case we didn't use the webhook to get the result of the scan, start a poll for the result
        # or in case we'd like to force the scan anyway from the configuration
        if not notify_url or wait_for_scan_anyway:
            scan_id = result.get('scan_id', '')
            if not scan_id:
                raise (AnalyzerRunException(
                    "no scan_id given by VirusTotal to retrieve the results"))
            # max 5 minutes waiting
            max_tries = 10
            poll_distance = 30
            got_result = False
            for chance in range(max_tries):
                time.sleep(poll_distance)
                logger.info("vt polling, try n.{}. job_id {}".format(
                    chance + 1, job_id))
                result = vt2_get.vt_get_report(api_key, scan_id, "hash")
                response_code = result.get('response_code', 1)
                # response code -2 means the we still have to wait
                if response_code == -2:
                    continue
                elif response_code == 1:
                    got_result = True
                    logger.info(
                        "vt polling retrieved the result correctly for job_id {}"
                        .format(job_id))
                    break
            if not got_result:
                logger.info(
                    "max VT polls tried without getting any result. job_id {}".
                    format(job_id))

        # pprint.pprint(result)
        report['report'] = result
    except AnalyzerRunException as e:
        error_message = "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}" \
                        "".format(job_id, analyzer_name, md5, filename, e)
        logger.error(error_message)
        report['errors'].append(error_message)
        report['success'] = False
    except Exception as e:
        traceback.print_exc()
        error_message = "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}" \
                        "".format(job_id, analyzer_name, md5, filename, e)
        logger.exception(error_message)
        report['errors'].append(str(e))
        report['success'] = False
    else:
        report['success'] = True

    general.set_report_and_cleanup(job_id, report, logger)

    logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id))

    return report
コード例 #6
0
ファイル: rtf_info.py プロジェクト: ninoseki/IntelOwl
def run(analyzer_name, job_id, filepath, filename, md5,
        additional_config_params):
    logger.info("started analyzer {} job_id {}"
                "".format(analyzer_name, job_id))
    report = general.get_basic_report_template(analyzer_name)
    try:
        results = {}

        rtfobj_results = {}
        binary = general.get_binary(job_id)
        rtfp = RtfObjParser(binary)
        rtfp.parse()
        rtfobj_results["ole_objects"] = []
        for rtfobj in rtfp.objects:
            if rtfobj.is_ole:
                class_name = rtfobj.class_name.decode()
                ole_dict = {
                    "format_id": rtfobj.format_id,
                    "class_name": class_name,
                    "ole_datasize": rtfobj.oledata_size,
                }
                if rtfobj.is_package:
                    ole_dict["is_package"] = True
                    ole_dict["filename"] = rtfobj.filename
                    ole_dict["src_path"] = rtfobj.src_path
                    ole_dict["temp_path"] = rtfobj.temp_path
                    ole_dict["olepkgdata_md5"] = rtfobj.olepkgdata_md5
                else:
                    ole_dict["ole_md5"] = rtfobj.oledata_md5
                if rtfobj.clsid:
                    ole_dict["clsid_desc"] = rtfobj.clsid_desc
                    ole_dict["clsid_id"] = rtfobj.clsid
                rtfobj_results["ole_objects"].append(ole_dict)
                # http://www.kb.cert.org/vuls/id/921560
                if class_name == "OLE2Link":
                    rtfobj_results["exploit_ole2link_vuln"] = True
                # https://www.kb.cert.org/vuls/id/421280/
                elif class_name.lower() == "equation.3":
                    rtfobj_results["exploit_equation_editor"] = True

        results["rtfobj"] = rtfobj_results

        report["report"] = results
    except AnalyzerRunException as e:
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.error(error_message)
        report["errors"].append(error_message)
        report["success"] = False
    except Exception as e:
        traceback.print_exc()
        error_message = (
            "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}"
            "".format(job_id, analyzer_name, md5, filename, e))
        logger.exception(error_message)
        report["errors"].append(str(e))
        report["success"] = False
    else:
        report["success"] = True

    general.set_report_and_cleanup(job_id, report)

    logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id))

    return report