-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvirustotal_api.py
155 lines (124 loc) · 4.58 KB
/
virustotal_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import os
import requests
import time
import json
def scan_file(file_path, api_key):
"""
Upload a file to VirusTotal for scanning
Args:
file_path (str): Path to the file to scan
api_key (str): VirusTotal API key
Returns:
dict: Response from VirusTotal API or None if failed
"""
if not api_key:
return None
url = "https://www.virustotal.com/vtapi/v2/file/scan"
params = {"apikey": api_key}
try:
with open(file_path, "rb") as file:
files = {"file": (os.path.basename(file_path), file)}
response = requests.post(url, files=files, params=params)
if response.status_code == 200:
return response.json()
else:
# Try with the larger file upload API if the file is too large
if response.status_code == 413:
return get_upload_url(file_path, api_key)
else:
print(f"Error: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Error uploading file: {str(e)}")
return None
def get_upload_url(file_path, api_key):
"""
Get a special URL for uploading larger files to VirusTotal
Args:
file_path (str): Path to the file to scan
api_key (str): VirusTotal API key
Returns:
dict: Response from VirusTotal API or None if failed
"""
url = "https://www.virustotal.com/vtapi/v2/file/scan/upload_url"
params = {"apikey": api_key}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
upload_url = response.json()["upload_url"]
with open(file_path, "rb") as file:
files = {"file": (os.path.basename(file_path), file)}
upload_response = requests.post(upload_url, files=files)
if upload_response.status_code == 200:
return upload_response.json()
else:
print(f"Error uploading to special URL: {upload_response.status_code} - {upload_response.text}")
return None
else:
print(f"Error getting upload URL: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Error in large file upload: {str(e)}")
return None
def get_scan_results(scan_id, api_key):
"""
Get the results of a VirusTotal scan
Args:
scan_id (str): The scan ID returned by VirusTotal
api_key (str): VirusTotal API key
Returns:
dict: Scan results from VirusTotal API or None if failed
"""
if not api_key or not scan_id:
return None
url = "https://www.virustotal.com/vtapi/v2/file/report"
params = {
"apikey": api_key,
"resource": scan_id
}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
result = response.json()
# Check if the scan is complete
if result.get("response_code") == 1:
return result
else:
# Scan is still processing
return {"status": "processing"}
else:
print(f"Error getting scan results: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Error getting scan results: {str(e)}")
return None
def search_hash(file_hash, api_key):
"""
Search for a file by its hash in VirusTotal
Args:
file_hash (str): The file hash (MD5, SHA-1, or SHA-256)
api_key (str): VirusTotal API key
Returns:
dict: Scan results from VirusTotal API or None if failed
"""
if not api_key or not file_hash:
return None
url = "https://www.virustotal.com/vtapi/v2/file/report"
params = {
"apikey": api_key,
"resource": file_hash
}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
result = response.json()
if result.get("response_code") == 1:
return result
else:
return {"status": "not_found"}
else:
print(f"Error searching hash: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Error searching hash: {str(e)}")
return None