-
Notifications
You must be signed in to change notification settings - Fork 0
/
url-malware-analyzer.py
172 lines (143 loc) · 9.01 KB
/
url-malware-analyzer.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import time # Importing the time module for adding delays
from base64 import urlsafe_b64encode # Importing the urlsafe_b64encode function from the base64 module for URL encoding
import time # Importing the time module for adding delays
from base64 import urlsafe_b64encode # Importing the urlsafe_b64encode function from the base64 module for URL encoding
import click # Importing the click module to help with command-line interface creation
import tldextract as tldextract
import whois
from defang import defang # Importing the defang function from the defang module
from defang import refang # Importing the refang function from the defang module
from selenium import webdriver # Importing the webdriver module from the selenium package for automated web browsing
from selenium.webdriver.chrome.options import \
Options # Importing the Options class from the selenium.webdriver.chrome.options module for Chrome configuration
from virustotal_python import \
Virustotal # Importing the Virustotal class from the virustotal_python module for interacting with the VirusTotal API
def get_virustotal_report(api_key, url):
"""
Returns the VirusTotal report for the given URL using the provided API key.
"""
vtotal = Virustotal(API_KEY=api_key) # Creating a Virustotal object with the given API key
url_id = urlsafe_b64encode(url.encode()).decode().strip("=") # Encoding the URL in base64 format for the VirusTotal API request
report = vtotal.request(f"urls/{url_id}").json() # Making a VirusTotal API request and getting the report in JSON format
return report # Returning the report
def display_vt_score_and_category(report):
"""
Displays the VirusTotal score and result category for the given report.
"""
last_analysis_stats = report["data"]["attributes"]["last_analysis_stats"] # Extracting the last analysis stats from the report JSON
malicious = last_analysis_stats["malicious"] # Extracting the number of malicious engines
total_engines = (
last_analysis_stats["malicious"]
+ last_analysis_stats["suspicious"]
+ last_analysis_stats["harmless"]
+ last_analysis_stats["undetected"]
) # Calculating the total number of engines that analyzed the URL
vt_score = f"{malicious}/{total_engines}" # Creating the VirusTotal score string
if malicious > 0: # If the number of malicious engines is greater than 0
result_category = "potentially malicious"
else:
result_category = "not detected as malicious" # Otherwise, the URL is not detected as malicious
click.echo(f"VirusTotal Score: {vt_score}") # Displaying the VirusTotal score
click.echo(f"Result Category: {result_category}") # Displaying the result category
def get_whois_info(domain):
"""
Retrieves WHOIS information for the given domain and returns relevant fields for security checks.
"""
w = whois.whois(domain) # Retrieve WHOIS information for the domain using the whois module
creation_date = w.creation_date[0].strftime('%Y-%m-%d %H:%M:%S') if isinstance(w.creation_date, list) and len(w.creation_date) > 0 else 'N/A' # Extract and format the creation date from the WHOIS information, or set to "N/A" if not available
expiration_date = w.expiration_date[0].strftime('%Y-%m-%d %H:%M:%S') if isinstance(w.expiration_date, list) and len(w.expiration_date) > 0 else 'N/A' # Extract and format the expiration date from the WHOIS information, or set to "N/A" if not available
updated_date = w.updated_date[0].strftime('%Y-%m-%d %H:%M:%S') if isinstance(w.updated_date, list) and len(w.updated_date) > 0 else 'N/A' # Extract and format the updated date from the WHOIS information, or set to "N/A" if not available
registrar = w.registrar if w.registrar else 'N/A' # Extract the registrar from the WHOIS information, or set to "N/A" if not available
registrant_name = w.name if w.name else 'N/A' # Extract the registrant name from the WHOIS information, or set to "N/A" if not available
registrant_email = w.email if w.email else 'N/A' # Extract the registrant email from the WHOIS information, or set to "N/A" if not available
registrant_phone = w.phone if w.phone else 'N/A' # Extract the registrant phone number from the WHOIS information, or set to "N/A" if not available
whois_info = f"""
Domain: {domain}
Creation Date: {creation_date}
Expiration Date: {expiration_date}
Updated Date: {updated_date}
Registrar: {registrar}
Registrant Name: {registrant_name}
Registrant Email: {registrant_email}
Registrant Phone: {registrant_phone}
""" # Construct a string containing the WHOIS information in a readable format
return whois_info # Return the WHOIS information as a string
def take_details_screenshot(url, screenshot_file):
"""
Takes a screenshot of the details page for the given URL and saves it to the specified file name.
"""
chrome_options = Options() # Creating a ChromeOptions object for configuring Chrome
chrome_options.add_argument("--headless") # Adding the headless argument to run Chrome in headless mode
chrome_options.add_argument("--window-size=1280,1024") # Setting the window size for the Chrome window
driver = webdriver.Chrome(options=chrome_options) # Creating a ChromeDriver object with the specified options
try:
driver.get(url) # Navigating to the specified URL
time.sleep(5) # Allowing some time for the page to load
driver.save_screenshot(screenshot_file) # Taking a screenshot of the page and saving it to the specified file name
click.echo(f"Details screenshot saved as: {screenshot_file}") # Displaying a message indicating that the screenshot has been saved
except Exception as e: # If an exception occurs while taking the screenshot
click.echo(f"Error taking details screenshot: {e}") # Displaying an error message
finally:
driver.quit() # Quitting the ChromeDriver object to free up system resources
def take_whois_screenshot(url, whois_screenshot_file):
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1280,1024")
driver = webdriver.Chrome(options=chrome_options)
url = f"https://www.virustotal.com/gui/domain/{url}/details"
try:
driver.get(url)
time.sleep(5) # Allow some time for the page to load
# Click on the WHOIS tab
whois_tab = driver.find_element(by=webdriver.common.by.By.XPATH, value="//domain-view[@name='domain-view']")
whois_tab.click()
time.sleep(3) # Allow some time for the WHOIS tab to load
driver.save_screenshot(whois_screenshot_file)
click.echo(f"WHOIS screenshot saved as: {whois_screenshot_file}")
except Exception as e:
click.echo(f"Error taking WHOIS screenshot: {e}")
finally:
driver.quit()
def defang_or_refang_url(url):
"""
Defangs or refangs the given URL depending on whether it is already defanged or not.
"""
if "[dot]" or "[.]" in url: # If either "[dot]" or "[.]" is in the URL
refanged_url = refang(url) # Refang the URL using the refang function from the defang module
click.echo(f"refanged URL: {refanged_url}") # Display a message indicating that the URL has been refanged
return (refanged_url) # Return the refanged URL
else: # Otherwise, the URL is not defanged
defanged_url = defang(url) # Defang the URL using the defang function from the defang module
click.echo(f"Defanged URL: {defanged_url}") # Display a message indicating that the URL has been defanged
return (defanged_url) # Return the defanged URL
def extract_domain(url):
"""
Extracts the domain from the given URL and returns it.
"""
extracted = tldextract.extract(url)
domain = extracted.domain + '.' + extracted.suffix
return domain
#
@click.command()
@click.option("--api_key", required=True, help="Your VirusTotal API key")
@click.option("--url", required=True, help="The URL to be analyzed")
@click.option("--details_screenshot", default="details_screenshot.png", help="The file name for the saved details screenshot")
@click.option("--whois_screenshot", default="whois_screenshot.png", help="The file name for the saved WHOIS screenshot")
def analyze_url(api_key, url, details_screenshot, whois_screenshot):
"""
Analyzes the given URL using the provided VirusTotal API key and saves a screenshot of the URL's details page and WHOIS tab.
"""
original_url = url
url = defang_or_refang_url(url)
domain = extract_domain(url)
click.echo(f"Domain: {domain}")
report = get_virustotal_report(api_key, url)
display_vt_score_and_category(report)
url_id = urlsafe_b64encode(url.encode()).decode().strip("=")
details_permalink = f"https://www.virustotal.com/gui/url/{url_id}/details"
whois = get_whois_info(domain)
print(whois)
take_details_screenshot(details_permalink, details_screenshot)
take_whois_screenshot(url, whois_screenshot)
if __name__ == '__main__':
analyze_url() # Run the analyze_url function when this script is executed directly