Forked from srinivas946/Virustotal_Funtional_Oriented.py
Created
December 24, 2020 17:42
-
-
Save toannd96/9f603feba59790e764beb021f766041b to your computer and use it in GitHub Desktop.
Functional Oriented style of program to verify the Threat Identity of an IOC provided by the user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests # to handle http and https requests and responses | |
import time # make program to sleep based on specified interval of time | |
# ------------------------------------- | |
# LIST OF VIRUS TOTAL REST API'S | |
# ------------------------------------- | |
IP_ADDRESS_API = "https://www.virustotal.com/vtapi/v2/ip-address/report" | |
DOMAIN_API = "https://www.virustotal.com/vtapi/v2/domain/report" | |
URL_REPORT_API = "https://www.virustotal.com/vtapi/v2/url/report" | |
URL_SCAN_API = "https://www.virustotal.com/vtapi/v2/url/scan" | |
FILE_REPORT_API = "https://www.virustotal.com/vtapi/v2/file/report" | |
FILE_SCAN_API = "https://www.virustotal.com/vtapi/v2/file/scan" | |
# ------------------------------------------------------------- | |
# GET IP ADDRESS THREAT INFORMATION - SINGLE AND BULK MODES | |
# ------------------------------------------------------------- | |
def get_ip_info(api, api_key, ip, mode): | |
# SINGLE -> This mode accept ip address as string eg: 8.8.8.8 | |
# BULK -> This mode accept ip address as bulk eg: ['8.8.8.8', '1.2.3.4'] or {'8.8.8.8', '1.2.3.4'} | |
if mode == 'single': | |
if isinstance(ip, str): | |
response = requests.get(url=api, params={'apikey': api_key, 'ip': ip}) | |
if response.status_code == 200: | |
return response.json() # parse the required information json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: raise TypeError(f'if mode is single, ip should be string but provided {type(ip)}') | |
elif mode == 'bulk': | |
ip_dict = {} | |
if isinstance(ip, (list, set, tuple)): | |
for i in range(1, len(ip)+1): | |
if i % 4 != 0: | |
response = requests.get(url=api, params={'apikey': api_key, 'ip': ip[i]}) | |
if response.status_code == 200: | |
ip_dict[ip[i]] = response.json() # parse the required information json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
ip_dict[ip[i]] = None | |
else: time.sleep(60) | |
return ip_dict | |
else: raise TypeError(f'if mode is bulk, ip should be either list or set or tuple, but provided {type(ip)}') | |
# --------------------------------------------------- | |
# GET DOMAINS INFORMATION - SINGLE AND BULK MODES | |
# --------------------------------------------------- | |
def get_domain_info(api, api_key, domain, mode): | |
# SINGLE -> This mode accept ip address as string eg: google.com | |
# BULK -> This mode accept ip address as bulk eg: ['google.com', 'abcd.com'] or {'google.com', 'abcd.com'} | |
if mode == 'single': | |
if isinstance(domain, str): | |
response = requests.get(url=api, params={'apikey': api_key, 'domain': domain}) | |
if response.status_code == 200: | |
return response.json() # parse the required information json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: raise TypeError(f'if mode is single, domain should be string but provided {type(domain)}') | |
elif mode == 'bulk': | |
domain_dict = {} | |
if isinstance(domain, (list, set, tuple)): | |
for i in range(1, len(domain)+1): | |
if i % 4 != 0: | |
response = requests.get(url=api, params={'apikey': api_key, 'domain': domain[i]}) | |
if response.status_code == 200: | |
domain_dict[domain[i]] = response.json() # parse the required information json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
domain_dict[domain[i]] = None | |
else: time.sleep(60) | |
return domain_dict | |
else: raise TypeError(f'if mode is bulk, domain should be either list or set or tuple, but provided {type(domain)}') | |
# -------------------------------------------------- | |
# GET URL INFORMATION - SINGLE AND BULK MODES | |
# -------------------------------------------------- | |
def get_url_info(api_type, url, api_key, mode): | |
# SINGLE -> This mode accept url as string eg: https://www.google.com/search | |
# BULK -> This mode accept ip address as bulk eg: ['https://url1.com', 'https://url2.com'] or {'https://url1.com', 'https://url2.com'} | |
response = None | |
if mode == 'single': | |
if isinstance(url, str): | |
if api_type == 'report': response = requests.get(url=URL_REPORT_API, params={'apikey': api_key, 'resource': url}) | |
elif api_type == 'scan': | |
headers = {'Content-Type': 'x-www-form-urlencoded'} | |
response = requests.post(url=URL_SCAN_API, data={'apikey': api_key, 'url': url}, headers=headers) | |
if response is not None: | |
if response.status_code == 200: | |
return response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: return None | |
else: raise TypeError(f'if mode is single, url should be string but provided {type(url)}') | |
elif mode == 'bulk': | |
url_dict = {} | |
if isinstance(url, (list, set, tuple)): | |
for i in range(1, len(url)+1): | |
if i%4 != 0: | |
if api_type == 'report': response = requests.get(url=URL_REPORT_API, params={'apikey': api_key, 'resource': url[i]}) | |
elif api_type == 'scan': | |
headers = {'Content-Type': 'x-www-form-urlencoded'} | |
response = requests.post(url=URL_SCAN_API, data={'apikey': api_key, 'url': url[i]}, headers=headers) | |
if response is not None: | |
if response.status_code == 200: url_dict[url[i]] = response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
url_dict[url[i]] = None | |
else: return None | |
else: time.sleep(60) | |
return url_dict | |
else: raise TypeError(f'if mode is bulk, url should be either list or set or tuple, but provided {type(url)}') | |
# ---------------------------------------------------- | |
# GET HASH INFORMATION - SINGLE AND BULK MODES | |
# ---------------------------------------------------- | |
def get_hash_info(hash, api_key, mode): | |
if mode == 'single': | |
if isinstance(hash, str): | |
response = requests.get(url=URL_REPORT_API, params={'apikey': api_key, 'resource': hash}) | |
if response.status_code == 200: | |
return response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: raise TypeError(f'if mode is single, hash should be string but provided {type(hash)}') | |
elif mode == 'bulk': | |
hash_dict = {} | |
if isinstance(hash, (list, set, tuple)): | |
for i in range(1, len(hash)+1): | |
if i%4 != 0: | |
response = requests.get(url=URL_REPORT_API, params={'apikey': api_key, 'resource': hash[i]}) | |
if response.status_code == 200: hash_dict[hash[i]] = response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
hash_dict[hash[i]] = None | |
else: time.sleep(60) | |
return hash_dict | |
else: raise TypeError(f'if mode is bulk, hash should be either list or set or tuple, but provided {type(hash)}') | |
# ------------------------------------------------- | |
# GET FILE REPORTS - SINGLE AND BULK MODES | |
# ------------------------------------------------- | |
def get_file_report(api, api_key, resource, mode): | |
# resource may be anything among MD5, SHA-1, SHA-256, scan_id | |
if mode == 'single': | |
if isinstance(resource, str): | |
response = requests.get(url=api, params={'apikey': api_key, 'resource': resource}) | |
if response.status_code == 200: | |
return response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: raise TypeError(f'if mode is single, resource should be string but provided {type(resource)}') | |
elif mode == 'bulk': | |
rsc_dict = {} | |
if isinstance(resource, (list, set, tuple)): | |
for i in range(1, len(resource)+1): | |
if i%4 != 0: | |
response = requests.get(url=api, params={'apikey': api_key, 'resource': resource[i]}) | |
if response.status_code == 200: rsc_dict[resource[i]] = response.json() # parse required infromation from json object | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
rsc_dict[resource[i]] = None | |
else: time.sleep(60) | |
return rsc_dict | |
else: raise TypeError(f'if mode is bulk, resource should be either list or set or tuple, but provided {type(resource)}') | |
# ----------------------------------------------------- | |
# UPLOAD FILE TO SCAN - SINGLE AND BULK MODES | |
# ----------------------------------------------------- | |
def upload_file_to_scan(api, api_key, file_path, mode): | |
# SINGLE Mode -> file path should be a string eg:'C:/path/to/file' | |
# BULK Mode -> file path should be a type among list, set and tuple eg:['C:/path/to/file1', 'C:/path/to/file2'] | |
if mode == 'single': | |
if isinstance(file_path, str): | |
files = {'file': ('test_file.exe', open(file_path, 'rb'))} | |
response = requests.post(url=api, params={'apikey': api_key}, files=files) | |
if response.status_code == 200: | |
return response.json() # parse required information from the resposne | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
return None | |
else: raise TypeError(f'if mode is single, file_path should be string but provided {type(file_path)}') | |
elif mode == 'bulk': | |
file_path_dict = {} | |
if isinstance(file_path, (list, tuple, set)): | |
for i in range(1, len(file_path)+1): | |
if i%4 != 0: | |
files = {'file': ('test_file.exe', open(file_path[i], 'rb'))} | |
response = requests.post(url=api, params={'apikey': api_key}, files=files) | |
if response.status_code == 200: file_path_dict[file_path[i]] = response.json() # parse required information from the resposne | |
else: | |
print(f'Status Code : {response.status_code} | Reason : {response.reason}') | |
file_path_dict[file_path[i]] = None | |
else: time.sleep(60) | |
return file_path_dict | |
else: raise TypeError(f'if mode is bulk, file_path should be either list or set or tuple, but provided {type(file_path)}') | |
# --------------------------------- | |
# PROGRAM EXECUTION STARTS HERE | |
# --------------------------------- | |
# GET IP ADDRESS THREAT INFORMATION - SINGLE AND BULK MODES | |
print(get_ip_info(api=IP_ADDRESS_API, api_key='your_api_key', ip='8.8.8.8', mode='single')) | |
print(get_ip_info(api=IP_ADDRESS_API, api_key='your_api_key', ip=['8.8.8.8', '1.2.3.4'], mode='bulk')) | |
# GET DOMAIN THREAT INFORMATION - SINGLE AND BULK MODES | |
print(get_domain_info(api=DOMAIN_API, api_key='your_api_key', domain='google.com', mode='single')) | |
print(get_domain_info(api=DOMAIN_API, api_key='your_api_key', domain=['google.com','amazon.com'], mode='bulk')) | |
# GET URL THREAT INFORMATION - SINGLE AND BULK MODES | |
print(get_url_info(api_type='report', url='https://someurl/subpath', api_key='your_api_key', mode='single')) | |
print(get_url_info(api_type='scan', url=['https://someurl/subpath', 'https://anotherurl/subpath'], api_key='your_api_key', mode='bulk')) | |
# GET HASH THREAT INFORMATION - SINGLE AND BULK MODES | |
print(get_hash_info(hash='somehashvalue', api_key='your_api_key', mode='single')) | |
print(get_hash_info(hash=['somehashvalue', 'hashvalue2'], api_key='your_api_key', mode='bulk')) | |
# GET FILE REPORT - SINGLE AND BULK MODES | |
print(get_file_report(api=FILE_REPORT_API, api_key='your_api_key', resource='md5value', mode='single')) | |
print(get_file_report(api=FILE_REPORT_API, api_key='your_api_key', resource=['md5value', 'sha256value'], mode='bulk')) | |
# UPLOAD FILE TO SCAN - SINGLE FILE AND BULK FILES | |
print(upload_file_to_scan(api=FILE_SCAN_API, api_key='your_api_key', file_path='C:/path/to/file', mode='single')) | |
print(upload_file_to_scan(api=FILE_SCAN_API, api_key='your_api_key', file_path=['C:/path/to/file1', 'C:/path/to/file2'], mode='bulk')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment