Skip to content

Instantly share code, notes, and snippets.

@dreizehnutters
Last active February 26, 2024 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dreizehnutters/e01d3a466617ef958a29fa4300036edc to your computer and use it in GitHub Desktop.
Save dreizehnutters/e01d3a466617ef958a29fa4300036edc to your computer and use it in GitHub Desktop.
export nessus reports via CLI
#!/usr/bin/env python3
__version__ = "1.0"
__about__ = "nessus report exporter"
from time import sleep
from os import environ
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# DEFAULTS
AK = environ.get('NESSUS_AK') # CHANGE ME
SK = environ.get('NESSUS_SK') # CHANGE ME
TEMPLATE_ID = 1321 # CHANGE ME
CHUNK_SIZE = 1024
NESSUS_INSTANCE = "localhost:8834"
OUT_DIR= "~/Desktop"
def trigger_download(scan_id, export_format='html'):
"""
return file_id
"""
burp0_url = f"https://{NESSUS_INSTANCE}/scans/{scan_id}/export"
burp0_headers = {"Content-Type": "application/json",\
"X-Requested-With": "XMLHttpRequest",\
"X-ApiKeys": f"accessKey={AK}; secretKey={SK}", "Connection": "close"}
burp0_json={"format": export_format, "template_id": TEMPLATE_ID}
resp = requests.post(burp0_url, headers=burp0_headers, json=burp0_json, verify=False, timeout=10)
if resp.status_code == 200:
try:
file_id = resp.json()['file']
except Exception as err:
raise Exception(err)
else:
raise Exception(f"[!] {resp.text} (scan_id: {scan_id})")
return file_id
def download_report(scan_id, file_id, filename):
"""
return True if downloaded else False
"""
burp0_url = f"https://{NESSUS_INSTANCE}/scans/{scan_id}/export/{file_id}/download"
burp0_headers = {"Content-Type": "application/json",\
"X-Requested-With": "XMLHttpRequest",\
"X-ApiKeys": f"accessKey={AK}; secretKey={SK};",\
"Connection": "close"}
resp = requests.get(burp0_url, headers=burp0_headers, verify=False, timeout=10)
if resp.status_code != 200:
return False
with open(f"{OUT_DIR}/{filename}", 'wb') as fd:
for chunk in resp.iter_content(CHUNK_SIZE):
fd.write(chunk)
return True
def select_scan_id():
"""
return scan_id from user input
"""
choices = get_all_scan_ids()
for idx, name in enumerate(choices):
print(f"[{idx}] {name[0]}")
choice = -1
while choice not in range(len(choices)):
try:
choice = int(input(f"[?] select a scan: 0-{len(choices)-1}: "))
print("")
except Exception as err:
continue
if choice in range(len(choices)):
return (choices[choice][0], choices[choice][1])
def get_all_scan_ids():
"""
return list of scan ids that are ready to be exported (not in trash and completed)
"""
burp0_url = f"https://{NESSUS_INSTANCE}/scans"
burp0_headers = {"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
"X-ApiKeys": f"accessKey={AK}; secretKey={SK};",
"Connection": "close"}
resp = requests.get(burp0_url, headers=burp0_headers, verify=False, timeout=10)
if resp.json()['scans'] is None:
exit("[!] no scans is ready to be exported")
trash_folder_id = [x['id'] for x in resp.json()['folders'] if x['type'] == 'trash'][-1]
scan_ids = [(x['name'], x['id']) for x in resp.json()['scans'] if x['status'] in ('completed', 'canceled', 'imported') and x['folder_id'] != trash_folder_id]
if len(scan_ids) > 0:
return scan_ids
exit("[!] no scans is ready to be exported")
def do_download(scan_id, file_id, filename):
"""
download file if status is ready
"""
code = False
n_sek = 0
while code is not True:
print(f"\t[z] the report is being generated since {n_sek:02d} sec", end='\r')
code = download_report(scan_id, file_id, filename)
sleep(1)
n_sek+=1
print(f"{' '*80}",end='\r')
if __name__ == '__main__':
option = input("[?] export all scans (y/n): ")
print("")
if (option.lower() == 'y') or (option.lower() == 'j'):
scan_ids = get_all_scan_ids()
else:
scan_ids = [select_scan_id()]
for scan_tuple in scan_ids:
print(f"[*] downloading report: '{scan_tuple[0]}'")
scan_id = scan_tuple[1]
for export_format in ['html', 'nessus']:
print(f"\t[.] getting the .{export_format} version")
try:
file_id = trigger_download(scan_id, export_format)
except Exception as err:
print(err)
continue
do_download(scan_id, file_id, filename=scan_tuple[0].replace(' ','_').replace('\\','_').replace('/','_')+f'.{export_format}')
print(f"{'-'*10}")
print("[$] done!")
@dreizehnutters
Copy link
Author

Nessus Report Exporter

This Python script automates the process of exporting Nessus scan reports in HTML and Nessus formats. It leverages the Nessus API to trigger report generation and download the resulting files. The script prompts users to select specific scans or export all available ones. It also includes error handling and retry mechanisms for downloading reports. Designed for ease of use and flexibility in managing Nessus scan data.

Features

  • Export Options: Choose to export specific scans or export all available scans.
  • Multiple Formats: Reports can be exported in both HTML and Nessus formats.
  • Automated Download: The script handles the process of triggering report generation and downloading the resulting files.
  • Error Handling: Includes robust error handling to manage unexpected situations during the export process.
  • Retry Mechanism: Incorporates a retry mechanism to handle cases where reports are not immediately available for download.

Usage

  1. Environment Setup: Ensure that the necessary environment variables NESSUS_AK and NESSUS_SK are set, corresponding to the Nessus access key and secret key.
  2. Customization: Optionally adjust the default configuration settings such as the Nessus template ID, chunk size for downloading, and output directory.
  3. Execution: Run the script, which will prompt you to choose between exporting specific scans or exporting all available scans.
  4. Report Formats: Reports will be exported in both HTML and Nessus formats and saved to the specified output directory.

Requirements

  • Python 3.x
  • Requests library (pip install requests)

Configuration

Ensure that the following environment variables are set:

  • NESSUS_AK: Nessus access key
  • NESSUS_SK: Nessus secret key

Additionally, you may customize the following default settings in the script:

  • TEMPLATE_ID: Nessus template ID for report generation
  • CHUNK_SIZE: Size of chunks for downloading files
  • OUT_DIR: Output directory for saving exported reports

Example

$ export NESSUS_AK="your_access_key"
$ export NESSUS_SK="your_secret_key"
$ python nessus_report_exporter.py

License

This project is licensed under the MIT License - see the LICENSE file for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment