Created
March 26, 2024 13:35
-
-
Save HackingLZ/43d78713d98b9de86f6c2c9ba61ee64d to your computer and use it in GitHub Desktop.
Download Nessus reports as CSV via API
This file contains hidden or 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 | |
import time | |
import os | |
# Nessus API credentials and host | |
nessus_url = "https://123.123.123.123:8834" | |
access_key = "x" | |
secret_key = "x" | |
headers = { | |
'X-ApiKeys': f'accessKey={access_key}; secretKey={secret_key}', | |
'Content-Type': 'application/json', | |
'Accept': 'application/json' | |
} | |
def get_scan_list(): | |
"""Get a list of all scans.""" | |
response = requests.get(f"{nessus_url}/scans", headers=headers, verify=False) | |
if response.status_code == 200: | |
return response.json()['scans'] | |
else: | |
print("Failed to retrieve scans list") | |
return [] | |
def export_scan(scan_id): | |
export_data = {'format': 'csv'} | |
response = requests.post(f'{nessus_url}/scans/{scan_id}/export', headers=headers, json=export_data, verify=False) | |
if response.status_code == 200: | |
return response.json()['file'] | |
else: | |
print(f"Failed to initiate export for scan {scan_id}. HTTP Status Code: {response.status_code}") | |
return None | |
def download_file(scan_id, file_id, filename): | |
if os.path.exists(filename): | |
print(f'File {filename} already exists. Skipping download.') | |
return | |
ready = False | |
while not ready: | |
check_response = requests.get(f'{nessus_url}/scans/{scan_id}/export/{file_id}/status', headers=headers, verify=False) | |
if check_response.status_code == 200: | |
if check_response.json().get('status') == 'ready': | |
ready = True | |
else: | |
print(f'Waiting for report {file_id} to be ready...') | |
time.sleep(5) | |
else: | |
print(f'Failed to check status for scan {scan_id}, file {file_id}. HTTP Status Code: {check_response.status_code}') | |
return | |
download_response = requests.get(f'{nessus_url}/scans/{scan_id}/export/{file_id}/download', headers=headers, stream=True, verify=False) | |
if download_response.status_code == 200: | |
with open(filename, 'wb') as f: | |
for chunk in download_response.iter_content(chunk_size=8192): | |
f.write(chunk) | |
print(f'Download completed for scan {scan_id}.') | |
else: | |
print(f'Failed to download report for scan {scan_id}, file {file_id}. HTTP Status Code: {download_response.status_code}') | |
if __name__ == "__main__": | |
requests.packages.urllib3.disable_warnings() | |
scans = get_scan_list() | |
for scan in scans: | |
scan_id = scan['id'] | |
filename = f'scan_{scan_id}_report.csv' | |
if not os.path.exists(filename): | |
file_id = export_scan(scan_id) | |
if file_id: | |
download_file(scan_id, file_id, filename) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment