Exemple #1
0
def vturl(vt, client, urlstring, stringvt):
    """
    vturl request vt api for url and return mardown string with informations from vt.
    :param vt:virus total import
    :param client:virustotal client api
    :param urlstring:string with the url to request
    :param stringvt:string to concatenate return 
    """
    url_id = vt.url_id(urlstring)
    url = client.get_object("/urls/{}".format(url_id))

    stringvt = '\n'.join([
        stringvt,
        "* first_submission_date: {}".format(url.first_submission_date)
    ])
    stringvt = '\n'.join(
        [stringvt, "* last_analysis_date: {}".format(url.last_analysis_date)])
    stringvt = '\n'.join([stringvt, "* categories: {}".format(url.categories)])
    stringvt = '\n'.join([
        stringvt, "* last_analysis_stats: {}".format(url.last_analysis_stats)
    ])
    stringvt = '\n'.join(
        [stringvt, "* total_votes: {}".format(url.total_votes)])
    stringvt = '\n'.join([
        stringvt,
        "* [VirusTotal source link](https://www.virustotal.com/gui/url/{}/detection)"
        .format(url_id)
    ])

    return stringvt, url.last_analysis_stats
Exemple #2
0
    def get_url_lookup(self, url: str) -> Optional[Dict[str, Any]]:
        url_storage_dir = get_cache_directory(self.storage_dir_vt,
                                              vt.url_id(url))
        if not url_storage_dir.exists():
            return None
        cached_entries = sorted(url_storage_dir.glob('*'), reverse=True)
        if not cached_entries:
            return None

        with cached_entries[0].open() as f:
            return json.load(f)
Exemple #3
0
    def run(self, indicators, indicator_type, maximum):
        """
        Utilises the vt-py library to query and store results
        relating to threat intelligence observables from the VirusTotal v3 API.
        """
        if maximum > 500:
            print(f'[VirusTotal] {maximum} > 500 | maximum of 500 API calls a day for free accounts')
            maximum = 500

        if indicator_type not in self.supported_indicators:
            print(f'[VirusTotal] does not support {indicator_type}')
            exit()

        if indicator_type not in indicators:
            print(f'[VirusTotal] {indicator_type} not found in provided observables')
            exit()

        print(f'[VirusTotal] Querying a maximum of {maximum} out of {len(indicators[indicator_type])} {indicator_type}')
        count = 0
        for i in indicators[indicator_type]:
            if count == maximum:
                break
            # used to get an indicator when in format {value, source}
            if isinstance(i, dict):
                i = i['value']

            # required from vt-py
            if indicator_type == "urls":
                i = vt.url_id(i)

            try:
                req = f'/{self.supported_indicators[indicator_type]}/{i}'
                res = self.vt_client.get_object(req)
                print(f"[VirusTotal] Success! {i}")
                self.output[indicator_type][i] = {}
                self.output[indicator_type][i]['last_analysis_stats'] = res.last_analysis_stats
                self.output[indicator_type][i]['last_analysis_results'] = res.last_analysis_results
                # note: according to the docs, virustotal has a 4req/min limit, but I have not encountered any rate limit
                # if this becomes an issue in the future, put a sleep() here
            except vt.error.APIError as e:
                if e.code == 'NotFoundError':
                    print(f"[VirsTotal] Failure! {i}")
                    pass
                else:
                    print("[VirusTotal] API Error:", e)
                continue
            except Exception as e:
                print("[VirusTotal] Something unexpected went wrong: ", e)
            count += 1

        self.vt_client.close()
        print("[VirusTotal] complete")
Exemple #4
0
 def send_url(self, string):
     try:
         url_id = vt.url_id(string)
         url = self.client.get_object(f"/urls/{url_id}")
         return self.get_data(url.last_analysis_stats)
     except Exception as e:
         try:
             if 'NotFoundError' in str(e):
                 analysis = self.client.scan_url(string)
                 return self._wait(analysis)
         except Exception as e:
             if 'InvalidArgumentError' in str(e):
                 return {"type":"error","message":'not valid url', 'name' : self.__class__.__name__ }
Exemple #5
0
    def url_lookup(self, url: str, force: bool = False) -> None:
        '''Lookup an URL on VT
        Note: force means 2 things:
            * (re)scan of the URL
            * re fetch the object from VT even if we already did it today

        Note: the URL will only be sent for scan if autosubmit is set to true in the config
        '''
        if not self.available:
            raise ConfigError('VirusTotal not available, probably no API key')

        url_storage_dir = get_cache_directory(self.storage_dir_vt,
                                              vt.url_id(url))
        url_storage_dir.mkdir(parents=True, exist_ok=True)
        vt_file = url_storage_dir / date.today().isoformat()

        scan_requested = False
        if self.autosubmit and force:
            self.client.scan_url(url)
            scan_requested = True

        if not force and vt_file.exists():
            return

        url_id = vt.url_id(url)
        for _ in range(3):
            try:
                url_information = self.client.get_object(f"/urls/{url_id}")
                with vt_file.open('w') as _f:
                    json.dump(url_information.to_dict(), _f)
                break
            except APIError as e:
                if not self.autosubmit:
                    break
                if not scan_requested and e.code == 'NotFoundError':
                    self.client.scan_url(url)
                    scan_requested = True
            time.sleep(5)
Exemple #6
0
def scanning(URL):
    import vt
    import nest_asyncio
    flag=0
    nest_asyncio.apply()
    client = vt.Client("<API KEY>")   
    url_id = vt.url_id(URL)
    url = client.get_object("/urls/{}".format(url_id))
    result = url.last_analysis_stats 
    for i in result:
        if i==1 and result[i]>0:
            flag = 1
        if i==2 and result[i]>0:
            flag=1       
    return flag 
Exemple #7
0
    def url_lookup(self, url: str):
        if not self.available:
            raise ConfigError('VirusTotal not available, probably no API key')

        url_id = vt.url_id(url)
        m = hashlib.md5()
        m.update(url_id.encode())

        url_storage_dir = self.storage_dir_vt / m.hexdigest()
        url_storage_dir.mkdir(parents=True, exist_ok=True)

        vt_file = url_storage_dir / date.today().isoformat()
        if vt_file.exists():
            return

        try:
            url_information = self.client.get_object(f"/urls/{url_id}")
            with vt_file.open('w') as _f:
                json.dump(url_information.to_dict(), _f)
        except vt.APIError as e:
            if self.autosubmit and e.code == 'NotFoundError':
                self.client.scan_url(url)
Exemple #8
0
 def __get_cache_directory(self, url: str) -> Path:
     url_id = vt.url_id(url)
     m = hashlib.md5()
     m.update(url_id.encode())
     return self.storage_dir_vt / m.hexdigest()
        if is_ioc_hash:
            # Convert hash to lower-case for consistency
            ioc = ioc.lower()
            args['ioc'] = ioc.lower()

            print(
                "[*] Use VT API to get info on hash ioc: {ioc}".format(**args))
            ioc_info = client.get_object("/files/" + ioc)

        else:
            args['ioc'] = ioc

            print(
                "[*] Use VT API to get info on url ioc: {ioc}".format(**args))
            url_id = vt.url_id(ioc)
            ioc_info = client.get_object("/urls/{}", url_id)

        print("[+] IOC: {ioc} Analysis".format(**args))
        print(json.dumps(ioc_info.last_analysis_stats, indent=4))

        if args['avs']:
            print("[+] IOC: {ioc} AV detections".format(**args))
            print(json.dumps(ioc_info.last_analysis_results, indent=4))

        if args['all']:
            print("[+] IOC: {ioc} All Info".format(**args))
            print(json.dumps(ioc_info.to_dict(), indent=4))

    except Exception as e:
        args['err'] = str(e)