-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnessus-scan-bulk-downloader.py
100 lines (71 loc) · 2.93 KB
/
nessus-scan-bulk-downloader.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
# https://community.tenable.com/s/question/0D53a00006TAN76/bulk-download-entire-scan-history
import os
import re
import time
import json
import requests
import unicodedata
from tqdm import tqdm
from urllib.parse import urljoin
# https://stackoverflow.com/questions/27981545/suppress-insecurerequestwarning-unverified-https-request-is-being-made-in-pytho
from requests.packages import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
output_dir = 'exports'
base_url = 'https://localhost:8834/'
# login info for local Nessus
username = ''
password = ''
export_format = 'db'
# password for nessus db
db_password = ''
if not os.path.exists(output_dir):
os.mkdir(output_dir)
def slugify(value, allow_unicode = False):
"""
Modified from https://github.com/django/django/blob/master/django/utils/text.py
Replace dot(.) with underscore(_) first to keep IP address formatting
"""
value = str(value).replace('.', '_')
if allow_unicode:
value = unicodedata.normalize('NFKC', value)
else:
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
value = re.sub(r'[^\w\s-]', '', value.lower())
return re.sub(r'[-\s]+', '-', value).strip('-_')
url = urljoin(base_url, 'session')
payload = {'username' : username, 'password' : password}
response = requests.request('POST', url, data = payload, verify = False)
token = json.loads(response.text)['token']
url = urljoin(base_url, 'scans')
headers = {'X-Cookie': 'token=' + token}
response = requests.request('GET', url, headers = headers, verify = False)
obj = json.loads(response.text)
id2foldername = {}
for folder_dict in obj['folders']:
directory = folder_dict['name']
id2foldername[folder_dict['id']] = directory
dir_path = os.path.join(output_dir, directory)
if not os.path.exists(dir_path):
os.mkdir(dir_path)
for scan_dict in tqdm(obj['scans']):
scan_id = scan_dict['id']
url = 'https://localhost:8834/scans/' + str(scan_id) + '/export'
payload = {'scan_id' : scan_id, 'format' : export_format, 'password' : db_password, 'template_id' : 'false'}
response = requests.request('POST', url, headers = headers, data = payload, verify = False)
file_id = json.loads(response.text)['file']
status = None
while status != 'ready':
time.sleep(1)
url = 'https://localhost:8834/scans/' + str(scan_id) + '/export/' + str(file_id) + '/status'
response = requests.request('GET', url, headers = headers, verify = False)
res_json = json.loads(response.text)
if 'status' in res_json:
status = res_json['status']
url = 'https://localhost:8834/scans/' + str(scan_id) + '/export/' + str(file_id) + '/download'
response = requests.request('GET', url, headers = headers, verify = False)
file_bin = response.content
folder_name = id2foldername[scan_dict['folder_id']]
scan_name = slugify(scan_dict['name']) + '.db'
output_file_name = os.path.join(output_dir, folder_name, scan_name)
with open(output_file_name, 'wb') as file:
file.write(file_bin)