-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create url_scan_report.py #193
Open
David-M-Berry
wants to merge
1
commit into
VirusTotal:master
Choose a base branch
from
David-M-Berry:patch-1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
""" | ||
This example program allows a user to pass a URL as a command line argument during script execution. | ||
|
||
EXAMPLE: python3 url_scan_report.py testphp.vulnweb.com | ||
|
||
This will return the list of security vendors who have marked the URL as clean or malicious, | ||
and can be used to score the trust worthiness of a URL. | ||
|
||
NOTICE: In order to use this program you will need an API key that has | ||
privileges for using the VirusTotal Feed API. | ||
|
||
Developed by @David-M-Berry | ||
""" | ||
|
||
import argparse | ||
import os | ||
import time | ||
import vt | ||
|
||
def scan_url(client, url): | ||
"""Initiates a scan for the given URL and returns the scan ID.""" | ||
print(f"Scanning URL: {url}") | ||
try: | ||
analysis = client.scan_url(url) | ||
print(f"URL scan started: {analysis.id}") | ||
return analysis.id | ||
except vt.error.APIError as e: | ||
print(f"APIError: {e}") | ||
except Exception as e: | ||
print(f"An error occurred during URL scan: {e}") | ||
return None | ||
|
||
def get_url_report(client, scan_id): | ||
"""Fetches the report for the given scan ID.""" | ||
print(f"Fetching report for scan ID: {scan_id}") | ||
try: | ||
# Fetch the analysis using the scan ID | ||
analysis = client.get_object(f"/analyses/{scan_id}") | ||
return analysis | ||
except vt.error.APIError as e: | ||
print(f"APIError: {e}") | ||
except Exception as e: | ||
print(f"An error occurred while fetching the report: {e}") | ||
return None | ||
|
||
def wait_for_scan_completion(client, scan_id, timeout=300): | ||
"""Waits for the scan to complete by checking the status periodically.""" | ||
print("Waiting for the scan to complete...") | ||
start_time = time.time() | ||
while time.time() - start_time < timeout: | ||
report = get_url_report(client, scan_id) | ||
if report.status == "completed": | ||
return report | ||
time.sleep(10) | ||
print("Scan did not complete in the expected time.") | ||
return None | ||
|
||
def format_report(report): | ||
"""Formats and prints the URL scan report.""" | ||
if not report: | ||
print("No report available.") | ||
return | ||
|
||
print(f"\nURL Scan Report:") | ||
print(f"Scan ID: {report.id}") | ||
print("Last analysis stats:") | ||
for key, value in report.stats.items(): | ||
print(f" {key}: {value}") | ||
print("\nDetailed analysis:") | ||
for engine, result in report.results.items(): | ||
print(f" {engine}: {result['category']}") | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description="Scan a URL with VirusTotal and get the report.") | ||
parser.add_argument("url", help="URL to scan") | ||
args = parser.parse_args() | ||
|
||
api_key = os.getenv('VT_API_KEY') | ||
if not api_key: | ||
print("Error: Please set the VT_API_KEY environment variable.") | ||
return | ||
|
||
client = vt.Client(api_key) | ||
|
||
try: | ||
scan_id = scan_url(client, args.url) | ||
if not scan_id: | ||
print("URL scan failed.") | ||
return | ||
|
||
report = wait_for_scan_completion(client, scan_id) | ||
format_report(report) | ||
|
||
except vt.error.APIError as e: | ||
print(f"APIError: {e}") | ||
if e.args[0] == 'ForbiddenError': | ||
print("You are not authorized to perform the requested operation. Please check your API key permissions.") | ||
except Exception as e: | ||
print(f"An error occurred: {e}") | ||
finally: | ||
client.close() | ||
|
||
if __name__ == "__main__": | ||
main() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Client object has a timeout option that can be used instead of doing this:
vt-py/vt/client.py
Line 234 in 03fd2f1