Exemple #1
0
def check_file(key, file):
    msg()                                                           # prints scanning message
    scanner = Virustotal(key)                                       # passing api key to Virustotal class
    scanner.file_scan(file)                                         # scans the file for virus
    with open(file, 'rb') as f:                                     # opens file in read binary mode
        read = f.read()                                             # reads opened file
        file_hash = hashlib.sha256(read).hexdigest()                # Get sha256 hash of file
    report = scanner.file_report([file_hash])    # passing hash value of file to file_report function and returns report
    try:
        print('\n\nREPORT:\nStatus code:', report['status_code'])   # Prints all the reports
        print('Scan date:', report['json_resp']['scan_date'])
        print('Verbose msg:', report['json_resp']['verbose_msg'])
        print('Antivirus Scanned:', report['json_resp']['total'])
        print('Positives:', report['json_resp']['positives'])
        print('sha256:', report['json_resp']['sha256'])
        print('md5:', report['json_resp']['md5'])
    except KeyError:
        print('\n""Maximum four scans per minute""')
Exemple #2
0
from virustotal_python import Virustotal
from pprint import pprint
from json2html import *
import json

vtotal = Virustotal(
    "50473a41f47913496c613e67dee646f6a36ebf434ce4e99fec30198f5014d29c")

resp = vtotal.file_report(
    ["09de776902ca7d32abdab8a7ccd177fb917addf502bd4bd5aa25a93ab41cc869"])
data = json.dumps(resp)
data = data.replace("'", '"')
html_parser = json2html.convert(json=data)
with open("./templates/program/data_tep.html", "w") as f:
    f.write(html_parser)
Exemple #3
0
class StartModule():
    def __init__(self):
        self._main_gui_func_ = 'isBadFile'
        self.__gui_label__ = 'Virustotal Search'

    def help(self):
        Logger.printMessage(
            message=ht.getFunctionsNamesFromModule('ht_virustotal'),
            debug_module=True)

    def isBadFileHash(self, fileHash, virustotal_api=None, session_id=None):
        try:
            if not virustotal_api:
                virustotal_api = ht.Config.getAPIKey('virustotal_api',
                                                     session_id)
            self.vtotal = Virustotal(virustotal_api)
            resp = self.vtotal.file_report([fileHash])
            if resp["status_code"] in (200, 204):
                if resp["status_code"] == 204:
                    Logger.printMessage(
                        message="isBadFileHash",
                        description="Testing - {hash} - Waiting 2 seconds...".
                        format(hash=fileHash),
                        debug_module=True)
                    time.sleep(2)
                    return self.isBadFileHash(fileHash, virustotal_api)
                while resp["json_resp"]["response_code"] == -2:
                    Logger.printMessage(
                        message="isBadFileHash",
                        description="Testing - {hash} - Waiting 2 seconds...".
                        format(hash=fileHash),
                        debug_module=True)
                    time.sleep(2)
                    return self.isBadFileHash(fileHash, virustotal_api)
                no_detected_list = []
                detected_list = []
                detected_types = []
                for antivirus in resp["json_resp"]["scans"]:
                    if resp["json_resp"]["scans"][antivirus]["detected"]:
                        detected_list.append(
                            (antivirus,
                             resp["json_resp"]["scans"][antivirus]["version"]))
                        if not resp["json_resp"]["scans"][antivirus][
                                "result"] in detected_types:
                            detected_types.append(resp["json_resp"]["scans"]
                                                  [antivirus]["result"])
                    else:
                        no_detected_list.append(
                            (antivirus,
                             resp["json_resp"]["scans"][antivirus]["version"]))
                if detected_list:
                    data = {}
                    data["detected_list"] = detected_list
                    data["detected_types"] = detected_types
                    data["no_detected_list"] = no_detected_list
                    return json.dumps({"Detected": data},
                                      indent=4,
                                      sort_keys=True)
                return json.dumps({"No detected": no_detected_list},
                                  indent=4,
                                  sort_keys=True)
            return resp
        except Exception as e:
            Logger.printMessage(message="isBadFileHash",
                                description=str(e),
                                is_error=True)
            return str(e)

    def isBadFile(self, filename, virustotal_api=None):
        try:
            if not virustotal_api:
                virustotal_api = ht.Config.config['API']['virustotal']
            Logger.printMessage(message="isBadFile",
                                description=filename,
                                debug_module=True)
            self.vtotal = Virustotal(virustotal_api)
            response = self.vtotal.file_scan(filename)
            if response["status_code"] == 200:
                scan_id = str(response["json_resp"]["scan_id"])
                time.sleep(2)
                resp = self.isBadFileHash(scan_id, virustotal_api)
                return resp
        except Exception as e:
            Logger.printMessage(message="isBadFile",
                                description=str(e),
                                is_error=True)
            return str(e)
Exemple #4
0
def main():

    parser = argparse.ArgumentParser(
        description=
        "Scan a single file in VirusTotal and waits until report is complete")
    parser.add_argument('file', help='File to be scanned')

    args = parser.parse_args()

    if 'VT_API_KEY' not in os.environ:
        LOGGER.error('VT_API_KEY environment variable not set.')
        sys.exit(SCAN_ERROR)

    LOGGER.debug('Initialzing VirusTotal API')
    vt_api_key = os.environ['VT_API_KEY']
    vt = Virustotal(vt_api_key)

    # Hash file
    LOGGER.info('Checking if report already exists via file hash.')
    file_hash = sha256sum(args.file)
    try:
        response = vt.file_report([file_hash])
    except ConnectionError as e:
        err_str = str(e)
        LOGGER.error(f"Connection error to VT: {err_str}.")
        sys.exit(SCAN_ERROR)

    ret = parse_response(response)

    # If report is available, just exit with the appropriate RC
    if ret != SCAN_NOT_FOUND:
        ret_str = RET_STR_INFECTED if ret else RET_STR_CLEAN
        LOGGER.info(f"Report found. Status: {ret_str}.")
        sys.exit(ret)

    # Send file to VT for scanning
    try:
        LOGGER.info(
            'Report not found. Sending file to VirusTotal for scanning.')
        vt.file_scan(args.file)
    except ConnectionError as e:
        err_str = str(e)
        LOGGER.error(f"Connection error to VT: {err_str}")
        sys.exit(SCAN_ERROR)

    while ret == SCAN_NOT_FOUND:
        LOGGER.info(f"Scan still running, sleeping for {WAIT_TIME} seconds.")
        sleep(WAIT_TIME)
        # Try again
        try:
            response = vt.file_report([file_hash])
        except ConnectionError as e:
            err_str = str(e)
            LOGGER.error(
                f"Temporary connection error to VT: {err_str}... Retrying in {WAIT_TIME} seconds."
            )
            continue

        ret = parse_response(response)

    ret_str = RET_STR_INFECTED if ret else RET_STR_CLEAN
    LOGGER.info(f"Scan finished. Status: {ret_str}.")
    sys.exit(ret)
class ExternalTesting:

    # This requires a virustotal API key
    VIRUSTOTAL = 4
    # This requires the installation of the Malice multiscanner along with installed scanner plugins
    MALICE = 2
    NONE = 0

    MALICE_SCANNERS = [
        'malice/avast', 'malice/avg', 'malice/clamav', 'malice/comodo',
        'malice/escan', 'malice/fprot', 'malice/fsecure', 'malice/mcafee',
        'malice/sophos', 'malice/zoner'
    ]

    # Initialize module logfile and tool output file to STDOUT, initialize output headers
    def __init__(self):
        self.logfile = stdout
        self.output = False
        self.virus_total = None
        self.virus_total_output_path = ''
        self.malice_output_path = ''
        self.scanners = ExternalTesting.NONE

    @staticmethod
    def check_or_make_path(target_path):
        if not path.isdir(target_path):
            mkdir(target_path)

    def get_scanners(self):
        return self.MALICE_SCANNERS

    # Specify module logfile manually
    def set_logfile(self, logfile_path):
        self.logfile = open(logfile_path, 'w')

    # Specify module logfile directory, but use default name for logfile
    def set_logfile_by_directory(self, logfile_directory):
        self.logfile = open(
            path.join(logfile_directory, 'external_scanner.log'), 'w')

    # Flush module logfile
    def flush_logfile(self):
        self.logfile.flush()

    # Close module logfile
    def close_logfile(self):
        if self.logfile != stdout:
            self.logfile.close()

    # Specify tool output file
    def set_output_directory(self, output_path):
        self.check_or_make_path(output_path)
        if self.scanners and self.VIRUSTOTAL:
            self.virus_total_output_path = path.join(output_path, 'VirusTotal')
            ExternalTesting.check_or_make_path(self.virus_total_output_path)
        if self.scanners and self.MALICE:
            self.malice_output_path = path.join(output_path, 'Malice')
            ExternalTesting.check_or_make_path(self.malice_output_path)
        self.output = True

    # Flush tool output file
    def flush_output(self):
        self.output.flush()

    # Close tool output file
    def close_output(self):
        if self.output != stdout:
            self.output.close()

    # Close all logfiles (tool output, module logs)
    def close(self):
        self.close_logfile()
        self.close_output()

    def set_virus_total_key(self, key):
        self.virus_total = Virustotal(key)

    def set_external_scanners(self, setting):
        if setting in [
                ExternalTesting.NONE, ExternalTesting.MALICE,
                ExternalTesting.VIRUSTOTAL,
                ExternalTesting.MALICE | ExternalTesting.VIRUSTOTAL
        ]:
            self.scanners = setting
            return True
        else:
            return False

    def check_virus_total(self):
        if self.virus_total:
            return True
        else:
            return False

    # This function expects input in the form of destination filename, md5 sum, and path to file to scan. The output is
    # a .json file (if the VirusTotal api is enabled) and an .md file (if the Malice command is enabled).
    def process_file_list_multiscanner(self, md5_list):
        if (self.scanners == self.NONE):
            return False
        if (self.scanners
                and self.VIRUSTOTAL) and not (self.check_virus_total()):
            raise AttributeError(
                'VirusTotal API invoked without providing a key using the virus_total_key(key) method'
            )
        for entry in md5_list:
            if self.scanners and self.VIRUSTOTAL:
                self.logfile.write('Invoking VirusTotal on {}.'.format(
                    entry[2]))
                destination_file_path = path.join(self.virus_total_output_path,
                                                  '{}.json'.format(entry[0]))
                print(destination_file_path)
                virus_total_report = self.virus_total.file_report([entry[1]])
                if self.output:
                    with open(destination_file_path, 'w') as write_file:
                        pprint(virus_total_report, write_file)
                        self.logfile.write(
                            "Wrote VirusTotal report for {} to {}".format(
                                entry[2], destination_file_path))
                else:
                    pprint(virus_total_report)
            if self.scanners and self.MALICE:
                self.logfile.write('Invoking Malice Scanner on {}.'.format(
                    entry[2]))
                destination_file_path = path.join(self.malice_output_path,
                                                  '{}.md'.format(entry[0]))
                malice_output = ""
                for scanner in self.MALICE_SCANNERS:
                    print(entry[2], scanner)
                    command = "docker run --rm -v {}:/malware:ro {} -t " \
                              "/malware/{}".format(path.dirname(entry[2]), scanner, path.basename(entry[2]))
                    malice = run(command,
                                 shell=True,
                                 encoding=getfilesystemencoding(),
                                 stdout=PIPE)
                    malice_output += malice.stdout
                if self.output:
                    with open(destination_file_path, 'w') as write_file:
                        write_file.write(malice_output)
                        self.logfile.write(
                            "Wrote Malice output {} to {}".format(
                                entry[2], destination_file_path))
                else:
                    print(malice_output)
        return True
        if "virustotal" in report_json and "sha256" in report_json[
                "virustotal"]:  # If VirusTotal report fetching was correctly conducted in cuckoo, use it
            c.execute('INSERT INTO samples (sha256, mark_count) VALUES (?, ?)',
                      (report_json["virustotal"]["sha256"],
                       report_json["virustotal"]["positives"]))
            sample_id = c.lastrowid
        else:  # If not, fetch report now
            sha256_hash = hashlib.sha256()
            with open(
                    os.path.join(cwd, "storage/analyses", analysis_dir,
                                 "binary"), "rb") as f:
                # Read and update hash string value in blocks of 4K
                for byte_block in iter(lambda: f.read(4096), b""):
                    sha256_hash.update(byte_block)
            resp = vtotal.file_report([sha256_hash.hexdigest()])["json_resp"]
            if resp["response_code"] is 0:
                unknown_from_virustotal.append(analysis_dir)
                c.execute(
                    'INSERT INTO samples (sha256, mark_count) VALUES (?, ?)',
                    (sha256_hash.hexdigest(), -1))
            else:
                c.execute(
                    'INSERT INTO samples (sha256, mark_count) VALUES (?, ?)',
                    (resp["sha256"], resp["positives"]))
            sample_id = c.lastrowid

        snapshots_fp = open(
            os.path.join(cwd, "storage/analyses", analysis_dir, "files",
                         "metrics.json"))
        snapshots_json = json.load(snapshots_fp)