def main(url): apikey=fetchapikey() vt=VirusTotalPublicApi(apikey) response = vt.get_domain_report(url) if "error" in response.keys(): apiresco="NaN" whoisres="NaN" subdomsi=[] resolute=[] whotulst=[] whoitime="WhoIs timestamp not found" dnsrecdt="DNS record date not found" scandate="Scan date not found" verbmesg="Please check your internet connection and the URL for typos and try again" reply = [apiresco, whoisres, subdomsi, resolute, whotulst, whoitime, dnsrecdt, scandate, verbmesg] else: apiresco=str(response["response_code"]) whoisres=str(getwhoisres(response)) whoitime=str(getwhoitime(response)) dnsrecdt=str(getdnsrecdt(response)) subdomsi=getsubdomsi(response) whotulst=getwhoisdat(response) resolute=getresolute(response) scandate=str(time.ctime(int(time.time()))) verbmesg=response["results"]["verbose_msg"] reply=[apiresco,whoisres,subdomsi,resolute,whotulst,whoitime,dnsrecdt,scandate,verbmesg] return reply
def test_get_domain_report(self): vt = PublicApi(API_KEY) try: print(json.dumps(vt.get_domain_report('www.wired.com'), sort_keys=False, indent=4)) except Exception as e: self.fail(e)
def test_get_domain_report(self): vt = PublicApi(API_KEY) try: print json.dumps(vt.get_domain_report('www.wired.com'), sort_keys=False, indent=4) except Exception as e: self.fail(e)
def vt(self, domain, conf, verbose): print('## Searching subdomains in Virus Total') if conf["VirusTotal"]["type"] == "public": vt = PublicApi(conf["VirusTotal"]["key"]) else: vt = PrivateApi(conf["VirusTotal"]["key"]) res = vt.get_domain_report(domain) try: for d in res['results']['subdomains']: print(d) except KeyError: pass
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
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
def handle_domain(actapi: act.api.Act, vtapi: VirusTotalApi, domain: Text, output_format: Text = "json") -> None: """Read IP address from stdin, query VirusTotal and output a JSON text readable by generic_uploaderr.py""" with no_ssl_verification(): response = vtapi.get_domain_report(domain) try: results = response['results'] except KeyError: logging.error("%s in handle_domain for %s", response, domain) sys.exit(1) if 'detected_urls' in results: for u in map(urllib.parse.urlparse, [x['url'] for x in results['detected_urls']]): add_uri(actapi, 'fqdn', domain, list(u)) if 'undetected_urls' in results: for u in map(urllib.parse.urlparse, [x[0] for x in results['undetected_urls']]): add_uri(actapi, 'fqdn', domain, list(u)) if 'resolutions' in results: for resolution in results['resolutions']: ip = resolution['ip_address'] # To figure out what kind of IP address we have, let the ipaddress module # parse the string and test for instance type as the platform distinguishes # between IPv4 and IPv6 addresses. try: act.api.helpers.handle_fact(actapi.fact('resolvesTo').source( 'fqdn', domain).destination(*act.api.helpers.ip_obj(ip)), output_format=output_format) except ValueError: continue # invalid address if 'detected_downloaded_samples' in results: for sample in results['detected_downloaded_samples']: my_uri = add_uri(actapi, 'fqdn', domain, ['network', domain, '', '', '', '']) act.api.helpers.handle_fact(actapi.fact('at').source( 'content', sample['sha256']).destination('uri', my_uri), output_format=output_format) act.api.helpers.handle_fact(actapi.fact('represents').source( 'hash', sample['sha256']).destination('content', sample['sha256']), output_format=output_format) handle_hexdigest(actapi, vtapi, sample['sha256'], output_format=output_format) if 'detected_communicating_samples' in results: for sample in results['detected_communicating_samples']: my_uri = add_uri(actapi, 'fqdn', domain, ['network', domain, '', '', '', '']) act.api.helpers.handle_fact(actapi.fact('connectsTo').source( 'content', sample['sha256']).destination('uri', my_uri), output_format=output_format) act.api.helpers.handle_fact(actapi.fact('represents').source( 'hash', sample['sha256']).destination('content', sample['sha256']), output_format=output_format) handle_hexdigest(actapi, vtapi, sample['sha256'], output_format=output_format)
# print("Urls: ",urls) # urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', text) # print("Original string: ",text) # print("Urls: ",urls) elif x == 4: # def(domain): url = raw_input("Enter the domain : ") pprint.pprint(threatcrowd.domain_report(url)) print "**" * 80 print "VIRUSTOTAL_REPORT " * 80 vt = VirusTotalPublicApi(API_KEY_VT) response = vt.get_domain_report(url) print(json.dumps(response, sort_keys=False, indent=4)) print " HYBRID_ANALYSIS " * 90 hybrid = HybridAnalysisConnector().action_quick_scan_url(url) pprint.pprint(hybrid) elif x == 5: # def (virus_name): av = raw_input("Enter the Virus Name : ") pprint.pprint(threatcrowd.antivirus_report(av)) else: print("Invalid input Please give a valid Input") # import requests, json
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()
def handle_domain( actapi: act.api.Act, vtapi: VirusTotalApi, domain: Text, output_format: Text = "json", ) -> None: """Read IP address from stdin, query VirusTotal and output a JSON text readable by generic_uploaderr.py""" with no_ssl_verification(): response = vtapi.get_domain_report(domain) try: results = response["results"] except KeyError: logging.error("%s in handle_domain for %s", response, domain) sys.exit(1) if "detected_urls" in results: for u in map(urllib.parse.urlparse, [x["url"] for x in results["detected_urls"]]): add_uri(actapi, "fqdn", domain, list(u)) if "undetected_urls" in results: for u in map(urllib.parse.urlparse, [x[0] for x in results["undetected_urls"]]): add_uri(actapi, "fqdn", domain, list(u)) if "resolutions" in results: for resolution in results["resolutions"]: ip = resolution["ip_address"] # To figure out what kind of IP address we have, let the ipaddress module # parse the string and test for instance type as the platform distinguishes # between IPv4 and IPv6 addresses. try: act.api.helpers.handle_fact( actapi.fact("resolvesTo").source( "fqdn", domain).destination(*act.api.helpers.ip_obj(ip)), output_format=output_format, ) except ValueError: continue # invalid address if "detected_downloaded_samples" in results: for sample in results["detected_downloaded_samples"]: my_uri = add_uri(actapi, "fqdn", domain, ["network", domain, "", "", "", ""]) act.api.helpers.handle_fact( actapi.fact("at").source("content", sample["sha256"]).destination( "uri", my_uri), output_format=output_format, ) act.api.helpers.handle_fact( actapi.fact("represents").source("hash", sample["sha256"]).destination( "content", sample["sha256"]), output_format=output_format, ) handle_hexdigest(actapi, vtapi, sample["sha256"], output_format=output_format) if "detected_communicating_samples" in results: for sample in results["detected_communicating_samples"]: my_uri = add_uri(actapi, "fqdn", domain, ["network", domain, "", "", "", ""]) act.api.helpers.handle_fact( actapi.fact("connectsTo").source("content", sample["sha256"]).destination( "uri", my_uri), output_format=output_format, ) act.api.helpers.handle_fact( actapi.fact("represents").source("hash", sample["sha256"]).destination( "content", sample["sha256"]), output_format=output_format, ) handle_hexdigest(actapi, vtapi, sample["sha256"], output_format=output_format)
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')
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")
class VT(object): """ Class to hold VirusTotal items. """ # # FUNCTIONS # """ Sets up a VirusTotal object with the public api. """ def __init__(self, vtpublicapi): self.vtpublicapi = vtpublicapi self.vt = VirusTotalPublicApi(self.vtpublicapi) def add_headers(self, inputheaders): """ Adds appropriate headers to input list. """ inputheaders.append('VirusTotal Detected URLs') inputheaders.append('VirusTotal Detected Communicating Samples') inputheaders.append('VirusTotal Detected Downloaded Samples') inputheaders.append('VirusTotal Link') def add_row(self, host, inputrow): """ Adds the pulled data to the input row. """ vtdetectedurls = vtdetectedcommunicatingsamples = \ vtdetecteddownloadedsamples = vturl = '' if libs.network.IsIPv4(host): vtresponse = self.vt.get_ip_report(host) while "response_code" not in vtresponse or \ (vtresponse["response_code"] != 200 and vtresponse["response_code"] != 403): time.sleep(60) # Sleep for the API throttling vtresponse = self.vt.get_ip_report(host) if "results" not in vtresponse: vtdetectedurls = "INVALID API KEY" elif "detected_urls" in vtresponse["results"]: vtdetectedurls = str( len(vtresponse["results"]["detected_urls"])) else: vtdetectedurls = str(0) if "results" not in vtresponse: vtdetectedcommunicatingsamples = "INVALID API KEY" elif "detected_communicating_samples" in vtresponse["results"]: vtdetectedcommunicatingsamples = str( len(vtresponse["results"]["detected_" "communicating_" "samples"])) else: vtdetectedcommunicatingsamples = str(0) vturl = "https://www.virustotal.com/en/ip-address/{}/information/"\ .format(host) else: vtresponse = self.vt.get_domain_report(host) while "response_code" not in vtresponse or \ (vtresponse["response_code"] != 200 and vtresponse["response_code"] != 403): time.sleep(60) # Sleep for the API throttling vtresponse = self.vt.get_domain_report(host) if "results" not in vtresponse: vtdetectedurls = "INVALID API KEY" elif "detected_urls" in vtresponse["results"]: vtdetectedurls = str( len(vtresponse["results"]["detected_urls"])) else: vtdetectedurls = str(0) if "results" not in vtresponse: vtdetectedcommunicatingsamples = "INVALID API KEY" elif "detected_communicating_samples" in vtresponse["results"]: vtdetectedcommunicatingsamples = str( len(vtresponse["results"]["detected_" "communicating_" "samples"])) else: vtdetectedcommunicatingsamples = str(0) if "results" not in vtresponse: vtdetecteddownloadedsamples = "INVALID API KEY" elif "detected_downloaded_samples" in vtresponse["results"]: vtdetecteddownloadedsamples = str( len(vtresponse["results"]["detected_" "downloaded_" "samples"])) else: vtdetecteddownloadedsamples = str(0) vturl = "https://www.virustotal.com/en/domain/{}/information/"\ .format(host) inputrow.append(vtdetectedurls) inputrow.append(vtdetectedcommunicatingsamples) inputrow.append(vtdetecteddownloadedsamples) inputrow.append(vturl)