Skip to content

Instantly share code, notes, and snippets.

@HackingLZ
Created March 26, 2024 13:35
Show Gist options
  • Save HackingLZ/43d78713d98b9de86f6c2c9ba61ee64d to your computer and use it in GitHub Desktop.
Save HackingLZ/43d78713d98b9de86f6c2c9ba61ee64d to your computer and use it in GitHub Desktop.
Download Nessus reports as CSV via API
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