Exemplo n.º 1
0
    def execute(self, request: ServiceRequest):
        try:
            self.client = Client(apikey=self.config.get(
                "api_key", request.get_param("api_key")),
                                 proxy=self.config.get('proxy') or None)
        except Exception as e:
            self.log.error("No API key found for VirusTotal")
            raise e

        if request.task.metadata.get('submitted_url',
                                     None) and request.task.depth == 0:
            response = self.scan_url(request)
        else:
            response = self.scan_file(request)
        if response:
            result = self.parse_results(response)
            request.result = result
        else:
            request.result = Result()
Exemplo n.º 2
0
def _download_from_vt(client: vt.Client, file_hash: str) -> bytes:
    """
    Download file from VT.

    :param vt.Client client: the VT client
    :param str file_hash: the file hash
    :rtype: bytes
    :return: the downloaded data
    :raises ValueError: in case of any error
    """
    try:
        buffer = io.BytesIO()
        client.download_file(file_hash, buffer)
        buffer.seek(0, 0)
        return buffer.read()
    except (IOError, vt.APIError) as e:
        raise ValueError(str(e))
    finally:
        # vt.Client likes to free resources at shutdown, and it can be used as context to ease that
        # Since the structure of the module does not play well with how MISP modules are organized
        #   let's play nice and close connections pro-actively (opened by "download_file")
        if client:
            client.close()
Exemplo n.º 3
0
class VirusTotalStatic(ServiceBase):
    def __init__(self, config=None):
        super(VirusTotalStatic, self).__init__(config)
        self.client = None

    def start(self):
        self.log.debug("VirusTotalStatic service started")

    def execute(self, request: ServiceRequest):
        try:
            self.client = Client(apikey=self.config.get(
                "api_key", request.get_param("api_key")),
                                 proxy=self.config.get('proxy') or None)
        except Exception as e:
            self.log.error("No API key found for VirusTotal")
            raise e

        if request.task.metadata.get('submitted_url',
                                     None) and request.task.depth == 0:
            response = self.scan_url(request)
        else:
            response = self.scan_file(request)
        if response:
            result = self.parse_results(response)
            request.result = result
        else:
            request.result = Result()

    def common_scan(self, type: str, sample, retried: int = 0):
        json_response = None
        if retried < MAX_RETRY:
            try:
                json_response = self.client.get_json(f"/{type}s/{sample}")
            except APIError as e:
                if "NotFoundError" in e.code:
                    self.log.warning(f"VirusTotal has nothing on this {type}.")
                elif "QuotaExceededError" in e.code:
                    self.log.warning("Quota Exceeded. Trying again in 60s")
                    time.sleep(60)
                    retried += 1
                    return self.common_scan(type, sample, retried)
                else:
                    self.log.error(e)
        return json_response

    def scan_file(self, request: ServiceRequest):
        return self.common_scan("file", request.sha256)

    def scan_url(self, request: ServiceRequest):
        url_id = base64.urlsafe_b64encode(
            request.task.metadata.get(
                'submitted_url').encode()).decode().strip("=")
        return self.common_scan("url", url_id)

    @staticmethod
    def parse_results(response: Dict[str, Any]):
        res = Result()
        response = response['data']

        url_section = ResultSection('VirusTotal report permalink',
                                    body_format=BODY_FORMAT.URL,
                                    body=json.dumps(
                                        {"url": response['links']['self']}))
        res.add_section(url_section)
        response = response['attributes']
        scans = response['last_analysis_results']
        av_hits = ResultSection('Anti-Virus Detections')
        av_hits.add_line(
            f'Found {response["last_analysis_stats"]["malicious"]} AV hit(s) from '
            f'{len(response["last_analysis_results"].keys())}')
        for majorkey, subdict in sorted(scans.items()):
            if subdict['category'] == "malicious":
                virus_name = subdict['result']
                av_hit_section = AvHitSection(majorkey, virus_name)
                av_hit_section.set_heuristic(
                    1, signature=f'{majorkey}.{virus_name}')
                av_hit_section.add_tag('av.virus_name', virus_name)
                av_hits.add_subsection(av_hit_section)

        res.add_section(av_hits)

        return res
Exemplo n.º 4
0
def new_client(httpserver):
    return Client('dummy_api_key',
                  host='http://' + httpserver.host + ':' +
                  str(httpserver.port))