def test_get_url_report(self):
        vt = PublicApi(API_KEY)

        try:
            print(json.dumps(vt.get_url_report('www.wired.com'), sort_keys=False, indent=4))
        except Exception as e:
            self.fail(e)
Beispiel #2
0
    def each_with_type(self, target, target_type):
        self.results = {}

        vt = VirusTotalPublicApi(self.api_key)

        if target_type == "url":
            response = vt.get_url_report(target)
        else:
            with open(target, "rb") as f:
                sha256 = hashlib.sha256(f.read()).hexdigest()
            response = vt.get_file_report(sha256)

        # if request successful
        if response["response_code"] == 200 and response["results"][
                "response_code"] == 1:
            self.results["scan_date"] = response["results"]["scan_date"]
            self.results["permalink"] = response["results"]["permalink"]
            self.results["positives"] = response["results"]["positives"]
            self.results["total"] = response["results"]["total"]
            self.results["scans"] = response["results"]["scans"]

            return True

        self.log("debug", "no report found")
        return False
Beispiel #3
0
def url_report(url: str) -> json:
    """
    Peticion a la API de vt para obtener el reporte de un analisis ya realizado por el
    :param url:
    :return:
    """
    vt = VirusTotalPublicApi(VIRUSTOTAL_API_KEY)
    response = vt.get_url_report(url)
    return json.dumps(response, sort_keys=False)
Beispiel #4
0
    def test_get_url_report(self):
        vt = PublicApi(API_KEY)

        try:
            print json.dumps(vt.get_url_report('www.wired.com'),
                             sort_keys=False,
                             indent=4)
        except Exception as e:
            self.fail(e)
Beispiel #5
0
def link_to_virustotal(link, pkt):
    ''' IN CASE WE FOUND GET link, WE SCAN IT '''
    print 'SCANNING %s'%link
    virus_total_instance = PublicApi('2e1d7b6e998ed0a9830269571ecffa110e41dd8bf34b88ad41e40b4351165d18')
    REQ = virus_total_instance.scan_url(link)
    print 'Waiting for virustotal'
    while True:
        if 'Scan finished' in str(virus_total_instance.get_url_report(link)):
            print 'Scan finished!'
            REP = virus_total_instance.get_url_report(link)['results']['positives']
            break
        else:
            print 'Naaa not yet'
    if REP == '0' or REP == 0:
        print 'SCANNED %s - VERDICT OK [REP=%s]'%(link,REP)
        pkt.accept()
    else:
        print 'SCANNED %s - VERDICT KO [REP=%s]'%(link,REP)
        pkt.drop()
    '''
    def run(self, resource):
        apikey = self.config['apikey']

        # https://developers.virustotal.com/v2.0/reference#url-report
        vt = VirusTotalPublicApi(apikey)
        response = vt.get_url_report(resource)
        
        # If VT has no record, we want to add results and totals fields
        if response.get('results').get('scan_id') == None:
            return (True, {"results": None})

        return (True, response)
Beispiel #7
0
class VirusTotalChecker(AbstractUrlChecker):
    def __init__(self, api_key, *args, **kwargs):
        self.vt = VirusTotalPublicApi(api_key=api_key)

    @staticmethod
    def _get_site_voting(scans: dict) -> dict:
        res = {}
        for _, v in scans.items():
            key = v['result'].split(' ')[0]
            res[key] = res.get(key, 0) + 1

        return res

    @staticmethod
    def _get_site_risks(site_voting: dict):
        if site_voting is None:
            return None
        return SiteRiskValues.risk if any(
            site_voting.get(x, 0) > 0
            for x in BAD_SITES) else SiteRiskValues.safe

    @staticmethod
    def _get_site_classifications(categories):
        # TODO: @amihay current library doesn't return categories
        # use native Api
        return {}

    # TODO: handle other exception as well
    @retry(wait_exponential_multiplier=2,
           wait_exponential_max=1000,
           retry_on_exception=retry_if_api_limit)
    def _get_url_report(self, url, timeout):
        url_report = self.vt.get_url_report(this_url=url, timeout=timeout)
        if url_report['response_code'] == 204:  # api limier
            raise ApiLimitException()
        return url_report

    def _get(self, url, timeout=None, *args, **kwargs) -> UrlResult:
        url_report = self._get_url_report(url=url, timeout=timeout)
        domain_report = self.vt.get_domain_report(this_domain=url)
        site_voting = self._get_site_voting(
            url_report['results']
            ['scans']) if 'scans' in url_report['results'] else None
        site_classfications = self._get_site_classifications(domain_report)
        url_result = UrlResult(url=url,
                               site_voting=site_voting,
                               site_risk=self._get_site_risks(site_voting),
                               site_classification=site_classfications)
        return url_result
Beispiel #8
0
def analyze_domain(domain):

    if domain in os.listdir(SCAN_RESULT_DIR):
        return

    print(domain)

    vt = VirusTotalPublicApi(API_KEY)

    domain_response = vt.get_domain_report(domain)

    if 'results' not in domain_response.keys():
        print('  - ERROR results not in domain_response keys')
        return True

    if domain_response['results']['verbose_msg'] == 'Domain not found':
        print('  - ERROR Domain not found')
        return True

    url_response = vt.get_url_report(domain)

    if 'results' not in url_response.keys():
        print('  - ERROR results not in url_response keys')
        return True


    if 'verbose_msg' in url_response['results'].keys() and url_response['results']['verbose_msg'] == 'Resource does not exist in the dataset': 
        vt.scan_url(domain)
        print('  - resource does not exist: asking scan')
        return False

        
    results = domain_response['results']

    if 'Websense ThreatSeeker category' in results.keys():
        url_response['Websense ThreatSeeker category'] = results['Websense ThreatSeeker category']

    if 'categories' in results.keys():
        url_response['categories'] = results['categories']

    if 'TrendMicro category' in results.keys():
        url_response['TrendMicro category'] = results['TrendMicro category']

    with open(os.path.join(SCAN_RESULT_DIR, domain), 'w') as data_file:
        data_file.write(json.dumps(url_response))

    return True
Beispiel #9
0
def vt_url(input):
    vt = VirusTotalPublicApi("87ab79d0a21d9a7ae5c5558969c7d6b38defa1901b77d27796ae466b3823c776")
    try:
        input_list = [input_item.strip() for input_item in input.split(",")]
        for ip in input_list:
            scan_report = vt.get_url_report(ip)
            return render_template(
                "vt-url.html",
                url_request=scan_report.get("results").get("url").replace(":", "[:]").replace(".", "[.]"),
                scan_date=scan_report.get("results").get("scan_date"),
                positives=scan_report.get("results").get("positives"),
                total=scan_report.get("results").get("total"),
                link=scan_report.get("results").get("permalink"),
            )

    except Exception as e:
        return render_template("vt-url.html", text="Error: Please try again.")
Beispiel #10
0
def check_domain(domain, API_KEY, t=5, verbose=False, whois=False, vt=False):
    try:
        requests.get('https://{}'.format(domain))
        if verbose:
            print('The domain {} exists'.format(domain))
        if whois:
            w = who_is(domain)
            if(w is not None):
                print(w)
        if vt:
            vt = VirusTotalPublicApi(API_KEY)
            response = vt.get_url_report('https://{}'.format(domain), scan='1')
            print(json.dumps(response, sort_keys=False, indent=4))
    except Exception:
        if verbose:
            print('The domain {} does not exist'.format(domain))
    time.sleep(t)
def main(url):
    apikey = fetchapikey()
    vt = VirusTotalPublicApi(apikey)
    response = vt.get_url_report(url)
    if "error" in response.keys():
        totalscn = "NaN"
        positscn = "NaN"
        verbmesg = "Please check your internet connection and the URL for typos and try again"
        scanidty = "Scan ID not fetched"
        scanurle = "Scan URL not fetched"
        scandate = "Scan date not fetched"
        lichtdic = []
        reply = [
            lichtdic, totalscn, positscn, scanurle, scandate, scanidty,
            verbmesg
        ]
    else:
        tablcont = response["results"]["scans"]
        scsource = list(tablcont.keys())
        detction, resulted, detailed, tuplsore = [], [], [], ()
        for sites in scsource:
            detction.append(str(tablcont[sites]["detected"]))
            resulted.append(str(tablcont[sites]["result"]).title())
            try:
                detailed.append(str(tablcont[sites]["detail"]))
            except KeyError:
                detailed.append("N/A")
        totalscn = str(response["results"]["total"])
        positscn = str(response["results"]["positives"])
        verbmesg = str(response["results"]["verbose_msg"])
        scanidty = str(response["results"]["scan_id"])
        scanurle = str(response["results"]["url"])
        scandate = str(response["results"]["scan_date"])
        lichtdic = []
        for i in range(len(scsource)):
            tuplsore = (scsource[i], detction[i], resulted[i], detailed[i])
            lichtdic.append(tuplsore)
        reply = [
            lichtdic, totalscn, positscn, scanurle, scandate, scanidty,
            verbmesg
        ]
    return reply
Beispiel #12
0
class VTAssessment:
    def __init__(self, site, client=None, api_key=None):
        self.site = site

        if not client and not api_key:
            self.client = VirusTotalPublicApi(api_key)
        elif not client:
            raise Exception("either client object or API-KEY was not provided")
        else:
            self.client = client

        self.response = None

        self.site_risk_results = pd.Series()

    def site_scanner(self, scan="1"):
        response = self.client.get_url_report(this_url=self.site, scan=scan)
        self.response = response
        return response

    def is_risk(self) -> bool:
        if len(self.site_risk_results) == 0:
            self._extract_site_risks()

        risks_num = self.site_risk_results.isin(SITE_RISKS).sum()
        return risks_num > 1

    def voting_categories(self):
        if len(self.site_risk_results) == 0:
            self._extract_site_risks()
        return self.site_risk_results.value_counts()

    def _extract_site_risks(self):
        scans = self.response["results"]["scans"]
        risks = [res["result"].replace("site", "").strip() for res in scans.values()]
        self.site_risk_results = pd.Series(risks)

    def is_old_data(self) -> bool:
        scan_time_str = self.response["results"]["scan_date"]
        scan_time = dt.datetime.strptime(scan_time_str, "%Y-%m-%d %H:%M:%S")
        return dt.datetime.now() - dt.timedelta(hours=0.5) > scan_time
Beispiel #13
0
    def each_with_type(self, target, target_type):
        self.results = {}

        vt = VirusTotalPublicApi(self.api_key)

        if target_type == 'url':
            response = vt.get_url_report(target)
        else:
            sha256 = hashlib.sha256(open(target, 'r').read()).hexdigest()
            response = vt.get_file_report(sha256)

        # if request successful
        if response['response_code'] == 200 and response['results']['response_code'] == 1:
            self.results['scan_date'] = response['results']['scan_date']
            self.results['permalink'] = response['results']['permalink']
            self.results['positives'] = response['results']['positives']
            self.results['total'] = response['results']['total']
            self.results['scans'] = response['results']['scans']

            return True

        self.log("debug", 'no report found')
        return False
Beispiel #14
0
    def check_url(self, message, input):
        vt = VirusTotalPublicApi(self.API_KEY)
        try:
            input_list = [
                input_item.strip() for input_item in input.split(',')
            ]
            for ip in input_list:
                scan_report = vt.get_url_report(ip)
                self.reply(
                    message, "VirusTotal Scan Result \n"
                    "URL: {url_request} \n"
                    "Scan date: {scan_date} \n"
                    "Detection rate: {positives} out of {total} \n"
                    "Permalink: {permalink}".format(
                        url_request=scan_report.get("results").get(
                            "url").replace(":", "[:]").replace(".", "[.]"),
                        scan_date=scan_report.get("results").get("scan_date"),
                        positives=scan_report.get("results").get("positives"),
                        total=scan_report.get("results").get("total"),
                        permalink=scan_report.get("results").get("permalink")))

        except Exception as e:
            self.reply(message,
                       "Request for " + input + " raised an exception!")
print("INFO: Pulling DNS Cache Data from System")
DNS_Entry = DNS_CACHE_ENTRY()
DNS_Entry.wDataLength = 1024
response = d_handle.DnsGetCacheDataTable(ctypes.byref(DNS_Entry))

if response == 0:
    print("Error code: {0}".format(k_handle.GetLastError()))

DNS_Entry = ctypes.cast(DNS_Entry.pNext, ctypes.POINTER(DNS_CACHE_ENTRY))

while True:
    try:
        print("DNS Entry {0} - Type {1}".format(DNS_Entry.contents.recName,
                                                DNS_Entry.contents.wType))
        DNS_Entry = ctypes.cast(DNS_Entry.contents.pNext,
                                ctypes.pointer(DNS_CACHE_ENTRY))
    except:
        break

if response > 0:
    vt = VirusTotalPublicApi(API_KEY)
    DNS_Entry_String = str(DNS_Entry.contents.recName)
    query = vt.get_url_report(DNS_Entry_String)
    pos_obj = json.dumps(query, sort_keys=False, indent=4)
    load = json.loads(pos_obj)
    print(load)
    for rating in load["results"]:
        if rating["positives"] == 0:
            print("false")
    def _virustotal_function(self, event, *args, **kwargs):
        """Function: perform different scans on the following types:
            ip addresses
            hash - this will attempt to find an existing file report on the hash
            domain
            url - this will attempt to find an existing file report on the url. If none exist, a new scan is queued
            file - this will start a new scan for the file and queue for a report later.
        """
        try:
            validateFields(('incident_id', 'vt_type'), kwargs)  # required

            # Init RequestsCommon with app.config options
            rc = RequestsCommon(opts=self.opts, function_opts=self.options)

            # Create a VirusTotal instance with the API Token and any proxies gathered by RequestsCommon
            vt = VirusTotal(self.options['api_token'], rc.get_proxies())

            # Get the function parameters:
            incident_id = kwargs.get("incident_id")  # number
            artifact_id = kwargs.get("artifact_id")  # number
            attachment_id = kwargs.get("attachment_id")  # number
            vt_type = kwargs.get("vt_type")  # text
            vt_data = kwargs.get("vt_data")  # text

            self.log = logging.getLogger(__name__)
            self.log.info("incident_id: %s", incident_id)
            self.log.info("artifact_id: %s", artifact_id)
            self.log.info("attachment_id: %s", attachment_id)
            self.log.info("vt_type: %s", vt_type)
            self.log.info("vt_data: %s", vt_data)

            yield StatusMessage("starting...")

            # determine next steps based on the API call to make
            if vt_type.lower() == 'file':
                entity = get_input_entity(get_resilient_client(self.resilient),
                                          incident_id, attachment_id,
                                          artifact_id)
                # Create a temporary file to write the binary data to.
                with tempfile.NamedTemporaryFile(
                        'w+b', delete=False) as temp_file_binary:
                    # Write binary data to a temporary file. Make sure to close the file here...this
                    # code must work on Windows and on Windows the file cannot be opened a second time
                    # While open.  Floss will open the file again to read the data, so close before
                    # calling Floss.
                    temp_file_binary.write(entity["data"])
                    temp_file_binary.close()
                    try:
                        response = vt.scan_file(temp_file_binary.name,
                                                filename=entity["name"])
                    except Exception as err:
                        raise err
                    finally:
                        os.unlink(temp_file_binary.name)

                file_result = self.return_response(response,
                                                   vt.get_file_report,
                                                   time.time())

                ## was a sha-256 returned? try an existing report first
                if file_result.get("sha256"):
                    response = vt.get_file_report(file_result.get("sha256"))
                    report_result = self.return_response(
                        response, None, time.time())

                    if report_result.get(
                            "response_code") and report_result.get(
                                "response_code") == 1:
                        result = report_result
                    else:
                        result = file_result

            elif vt_type.lower() == 'url':
                # attempt to see if a report already exists
                response = vt.get_url_report(vt_data)
                result = self.return_response(response, None, time.time())

                # check if result is not found, meaning no report exists
                if result['response_code'] == RC_NOT_FOUND:
                    response = vt.scan_url(vt_data)
                    result = self.return_response(response, vt.get_url_report,
                                                  time.time())

            elif vt_type.lower() == 'ip':
                response = vt.get_ip_report(vt_data)
                result = self.return_response(response, None, time.time())

            elif vt_type.lower() == 'domain':
                response = vt.get_domain_report(vt_data)
                result = self.return_response(response, None, time.time())

            elif vt_type.lower() == 'hash':
                response = vt.get_file_report(vt_data)
                result = self.return_response(response, None, time.time())

            else:
                raise ValueError(
                    "Unknown type field: {}. Check workflow pre-processor script."
                    .format(vt_type))

            results = {"scan": result}

            self.log.debug("scan: {}".format(results))

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            yield FunctionError()
Beispiel #17
0
class VirusTotalAnalyzer(Analyzer):

    def __init__(self):
        Analyzer.__init__(self)
        self.service = self.get_param('config.service', None, 'Service parameter is missing')
        self.virustotal_key = self.get_param('config.key', None, 'Missing VirusTotal API key')
        self.polling_interval = self.get_param('config.polling_interval', 60)
        self.proxies = self.get_param('config.proxy', None)
        self.vt = VirusTotalPublicApi(self.virustotal_key, self.proxies)

    def wait_file_report(self, id):
        results = self.check_response(self.vt.get_file_report(id))
        code = results.get('response_code', None)
        if code == 1:
            self.report(results)
        else:
            time.sleep(self.polling_interval)
            self.wait_file_report(id)

    def wait_url_report(self, id):
        results = self.check_response(self.vt.get_url_report(id))
        code = results.get('response_code', None)
        if code == 1 and (results.get('scan_id') == id):
            self.report(results)
        else:
            time.sleep(self.polling_interval)
            self.wait_url_report(id)

    def check_response(self, response):
        if type(response) is not dict:
            self.error('Bad response : ' + str(response))
        status = response.get('response_code', -1)
        if status == 204:
            self.error('VirusTotal api rate limit exceeded (Status 204).')
        if status != 200:
            self.error('Bad status : ' + str(status))
        results = response.get('results', {})
        if 'Missing IP address' in results.get('verbose_msg', ''):
            results['verbose_msg'] = 'IP address not available in VirusTotal'
        return results

        # 0 => not found
        # -2 => in queue
        # 1 => ready

    def read_scan_response(self, response, func):
        results = self.check_response(response)
        code = results.get('response_code', None)
        scan_id = results.get('scan_id', None)
        if code == 1 and scan_id is not None:
            func(scan_id)
        else:
            self.error('Scan not found')

    def summary(self, raw):
        taxonomies = []
        level = "info"
        namespace = "VT"
        predicate = "GetReport"
        value = "0"

        if self.service == "scan":
            predicate = "Scan"

        result = {
            "has_result": True
        }

        if raw["response_code"] != 1:
            result["has_result"] = False

        result["positives"] = raw.get("positives", 0)
        result["total"] = raw.get("total", 0)

        if "scan_date" in raw:
            result["scan_date"] = raw["scan_date"]

        if self.service == "get":
            if "scans" in raw:
                result["scans"] = len(raw["scans"])
                value = "{}/{}".format(result["positives"], result["total"])
                if result["positives"] == 0:
                    level = "safe"
                elif result["positives"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

            if "resolutions" in raw:
                result["resolutions"] = len(raw["resolutions"])
                value = "{} resolution(s)".format(result["resolutions"])
                if result["resolutions"] == 0:
                    level = "safe"
                elif result["resolutions"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"
            if "detected_urls" in raw:
                result["detected_urls"] = len(raw["detected_urls"])
                value = "{} detected_url(s)".format(result["detected_urls"])
                if result["detected_urls"] == 0:
                    level = "safe"
                elif result["detected_urls"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

            if "detected_downloaded_samples" in raw:
                result["detected_downloaded_samples"] = len(
                    raw["detected_downloaded_samples"])

        if self.service == "scan":
            if "scans" in raw:
                result["scans"] = len(raw["scans"])
                value = "{}/{}".format(result["positives"], result["total"])
                if result["positives"] == 0:
                    level = "safe"
                elif result["positives"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

        taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
        return {"taxonomies": taxonomies}

    def run(self):
        if self.service == 'scan':
            if self.data_type == 'file':
                filename = self.get_param('filename', 'noname.ext')
                filepath = self.get_param('file', None, 'File is missing')
                self.read_scan_response(
                    self.vt.scan_file(filepath, from_disk=True, filename=filename),
                    self.wait_file_report
                )
            elif self.data_type == 'url':
                data = self.get_param('data', None, 'Data is missing')
                self.read_scan_response(
                    self.vt.scan_url(data), self.wait_url_report)
            else:
                self.error('Invalid data type')
        elif self.service == 'get':
            if self.data_type == 'domain':
                data = self.get_param('data', None, 'Data is missing')
                self.report(self.check_response(
                    self.vt.get_domain_report(data)))
            elif self.data_type == 'fqdn':
                data = self.get_param('data', None, 'Data is missing')
                self.report(self.check_response(
                    self.vt.get_domain_report(data)))
            elif self.data_type == 'ip':
                data = self.get_param('data', None, 'Data is missing')
                self.report(self.check_response(self.vt.get_ip_report(data)))
            elif self.data_type == 'file':
                hashes = self.get_param('attachment.hashes', None)
                if hashes is None:
                    filepath = self.get_param('file', None, 'File is missing')
                    hash = hashlib.sha256(open(filepath, 'rb').read()).hexdigest()
                else:
                    # find SHA256 hash
                    hash = next(h for h in hashes if len(h) == 64)

                self.report(self.check_response(self.vt.get_file_report(hash)))
            elif self.data_type == 'hash':
                data = self.get_param('data', None, 'Data is missing')
                self.report(self.check_response(self.vt.get_file_report(data)))
            elif self.data_type == 'url':
                data = self.get_param('data', None, 'Data is missing')
                self.report(self.check_response(self.vt.get_url_report(data)))
            else:
                self.error('Invalid data type')
        else:
            self.error('Invalid service')
Beispiel #18
0
class VirusTotalAnalyzer(Analyzer):
    def __init__(self):
        Analyzer.__init__(self)
        self.service = self.get_param("config.service", None,
                                      "Service parameter is missing")
        self.virustotal_key = self.get_param("config.key", None,
                                             "Missing VirusTotal API key")
        self.polling_interval = self.get_param("config.polling_interval", 60)
        self.rescan_hash_older_than_days = self.get_param(
            "config.rescan_hash_older_than_days", None)
        self.highlighted_antivirus = self.get_param(
            "config.highlighted_antivirus", None)
        self.download_sample = self.get_param("config.download_sample", False)
        self.download_sample_if_highlighted = self.get_param(
            "config.download_sample_if_highlighted", False)
        self.obs_path = None
        self.proxies = self.get_param("config.proxy", None)
        if (self.download_sample or self.download_sample_if_highlighted
                or self.service == "download"):
            self.vt_pay = PrivateApi(self.virustotal_key, self.proxies)
        self.vt = PublicApi(self.virustotal_key, self.proxies)

    def get_file(self, hash):
        self.obs_path = "{}/{}".format(tempfile.gettempdir(), hash)
        response = self.vt_pay.get_file(hash)
        if response.get("response_code", None) == 200:
            with open(self.obs_path, "wb") as f:
                f.write(response["results"])
            kind = filetype.guess(self.obs_path)
            if kind and kind.extension != None:
                os.rename(self.obs_path,
                          "{}.{}".format(self.obs_path, kind.extension))
                self.obs_path = "{}.{}".format(self.obs_path, kind.extension)

    def wait_file_report(self, id):
        results = self.check_response(self.vt.get_file_report(id))
        code = results.get("response_code", None)
        if code == 1:
            if self.data_type == "hash" and (
                    self.download_sample or
                (self.download_sample_if_highlighted
                 and self.highlighted_antivirus and any([
                     results.get("scans", {}).get(av, {}).get(
                         "detected", None) == False
                     for av in self.highlighted_antivirus
                 ]))):
                self.get_file(self.get_param("data", None, "Data is missing"))
            self.report(results)
        else:
            time.sleep(self.polling_interval)
            self.wait_file_report(id)

    def wait_url_report(self, id):
        results = self.check_response(self.vt.get_url_report(id))
        code = results.get("response_code", None)
        if code == 1 and (results.get("scan_id") == id):
            self.report(results)
        else:
            time.sleep(self.polling_interval)
            self.wait_url_report(id)

    def check_response(self, response):
        if type(response) is not dict:
            self.error("Bad response : " + str(response))
        status = response.get("response_code", -1)
        if status == 204:
            self.error("VirusTotal api rate limit exceeded (Status 204).")
        if status != 200:
            self.error("Bad status : " + str(status))
        results = response.get("results", {})
        if "Missing IP address" in results.get("verbose_msg", ""):
            results["verbose_msg"] = "IP address not available in VirusTotal"
        return results

        # 0 => not found
        # -2 => in queue
        # 1 => ready

    def read_scan_response(self, response, func):
        results = self.check_response(response)
        code = results.get("response_code", None)
        scan_id = results.get("scan_id", None)
        if code == 1 and scan_id is not None:
            func(scan_id)
        else:
            self.error("Scan not found")

    def artifacts(self, raw):
        artifacts = []
        if self.obs_path:
            tags = []
            # This will work only in scan/rescan workflow, not in download only
            if self.highlighted_antivirus:
                for av in self.highlighted_antivirus:
                    detected = raw.get("scans",
                                       {}).get(av, {}).get("detected", None)
                    if detected == False:
                        tags.append("to_{}".format(av))
            artifacts.append(
                self.build_artifact("file", self.obs_path, tags=tags))
        return artifacts

    def summary(self, raw):
        taxonomies = []
        level = "info"
        namespace = "VT"
        predicate = "GetReport"
        value = "0"

        if self.service == "scan":
            predicate = "Scan"
        elif self.service == "rescan":
            predicate = "Rescan"
        elif self.service == "download":
            return {"taxonomies": taxonomies}

        result = {"has_result": True}

        if raw["response_code"] != 1:
            result["has_result"] = False

        result["positives"] = raw.get("positives", 0)
        result["total"] = raw.get("total", 0)

        if "scan_date" in raw:
            result["scan_date"] = raw["scan_date"]

        if self.service == "get":
            if "scans" in raw:
                result["scans"] = len(raw["scans"])
                value = "{}/{}".format(result["positives"], result["total"])
                if result["positives"] == 0:
                    level = "safe"
                elif result["positives"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

            if "resolutions" in raw:
                result["resolutions"] = len(raw["resolutions"])
                value = "{} resolution(s)".format(result["resolutions"])
                if result["resolutions"] == 0:
                    level = "safe"
                elif result["resolutions"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

            if "detected_urls" in raw:
                result["detected_urls"] = len(raw["detected_urls"])
                value = "{} detected_url(s)".format(result["detected_urls"])
                if result["detected_urls"] == 0:
                    level = "safe"
                elif result["detected_urls"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

            if "detected_downloaded_samples" in raw:
                result["detected_downloaded_samples"] = len(
                    raw["detected_downloaded_samples"])

        if self.service in ["scan", "rescan"]:
            if "scans" in raw:
                result["scans"] = len(raw["scans"])
                value = "{}/{}".format(result["positives"], result["total"])
                if result["positives"] == 0:
                    level = "safe"
                elif result["positives"] < 5:
                    level = "suspicious"
                else:
                    level = "malicious"

        taxonomies.append(
            self.build_taxonomy(level, namespace, predicate, value))

        if self.highlighted_antivirus:
            for av in self.highlighted_antivirus:
                detected = raw.get("scans", {}).get(av,
                                                    {}).get("detected", None)
                if detected == False:
                    taxonomies.append(
                        self.build_taxonomy("info", namespace, av,
                                            "Not detected!"))

        return {"taxonomies": taxonomies}

    def run(self):
        if self.service == "scan":
            if self.data_type == "file":
                filename = self.get_param("filename", "noname.ext")
                filepath = self.get_param("file", None, "File is missing")
                self.read_scan_response(
                    self.vt.scan_file(filepath,
                                      from_disk=True,
                                      filename=filename),
                    self.wait_file_report,
                )
            elif self.data_type == "url":
                data = self.get_param("data", None, "Data is missing")
                self.read_scan_response(self.vt.scan_url(data),
                                        self.wait_url_report)
            else:
                self.error("Invalid data type")

        elif self.service == "rescan":
            if self.data_type == "hash":
                data = self.get_param("data", None, "Data is missing")
                self.read_scan_response(self.vt.rescan_file(data),
                                        self.wait_file_report)
            else:
                self.error("Invalid data type")

        elif self.service == "download":
            if self.data_type == "hash":
                data = self.get_param("data", None, "Data is missing")
                self.get_file(data)
                self.report({"message": "file downloaded"})

        elif self.service == "get":
            if self.data_type == "domain":
                data = self.get_param("data", None, "Data is missing")
                results = self.check_response(self.vt.get_domain_report(data))

            elif self.data_type == "fqdn":
                data = self.get_param("data", None, "Data is missing")
                results = self.check_response(self.vt.get_domain_report(data))

            elif self.data_type == "ip":
                data = self.get_param("data", None, "Data is missing")
                results = self.check_response(self.vt.get_ip_report(data))

            elif self.data_type == "file":
                hashes = self.get_param("attachment.hashes", None)
                if hashes is None:
                    filepath = self.get_param("file", None, "File is missing")
                    hash = hashlib.sha256(open(filepath,
                                               "rb").read()).hexdigest()
                else:
                    hash = next(h for h in hashes if len(h) == 64)
                results = self.check_response(self.vt.get_file_report(hash))

            elif self.data_type == "hash":
                data = self.get_param("data", None, "Data is missing")
                results = self.check_response(self.vt.get_file_report(data))

            elif self.data_type == "url":
                data = self.get_param("data", None, "Data is missing")
                results = self.check_response(self.vt.get_url_report(data))
            else:
                self.error("Invalid data type")

            # if aged and enabled rescan
            if self.data_type == "hash" and self.rescan_hash_older_than_days:
                if (datetime.strptime(results["scan_date"],
                                      "%Y-%m-%d %H:%M:%S") - datetime.now()
                    ).days > self.rescan_hash_older_than_days:
                    self.read_scan_response(self.vt.rescan_file(data),
                                            self.wait_file_report)

            # download if hash, dangerous and not seen by av
            if (self.data_type == "hash"
                    and (results.get("response_code", None) == 1)
                    and (results.get("positives", 0) >= 5)
                    and (self.download_sample or
                         (self.download_sample_if_highlighted
                          and self.highlighted_antivirus and any([
                              results.get("scans", {}).get(av, {}).get(
                                  "detected", None) == False
                              for av in self.highlighted_antivirus
                          ])))):
                self.get_file(data)
            self.report(results)

        else:
            self.error("Invalid service")