Skip to content

Instantly share code, notes, and snippets.

@barkink
Created November 3, 2016 08:43
Show Gist options
  • Save barkink/fefab5d397df84294094a7a1f1d41d8e to your computer and use it in GitHub Desktop.
Save barkink/fefab5d397df84294094a7a1f1d41d8e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import sys
import os
import io
import argparse
import getpass
import json
sys.path.append('../')
from nessrest import ness6rest
kullanici = ''
parola = ''
sunucu = ''
# Print error function
def print_err(str_error, fatal=False):
sys.stderr.write('ERROR: ' + str_error + '\n')
if fatal:
exit('Exiting due to fatal error.')
# Parse command line options
parser = argparse.ArgumentParser(description='Download completed nessus scans.')
parser.add_argument('-s', '--server', help='IP address of Nessus API endpoint', default=sunucu)
parser.add_argument('-p', '--port', help='port number of Nessus API endpoint', type=int, default=8834)
parser.add_argument('-f', '--format', help='report format', choices=['nessus', 'html', 'csv', 'db'], default='nessus')
parser.add_argument('--dbpasswd', help='scan db format password', default=None)
parser.add_argument('-c', '--capath', help='certificate authority path', default=None)
parser.add_argument('-t', '--trash', help='include trash folder', action='store_true', default=False)
parser.add_argument('--insecure', help='boldly go forth and ignore cert errors', action='store_true', default=True)
group = parser.add_mutually_exclusive_group()
group.add_argument('-k', '--keyfile', help='API key file in json format')
group.add_argument('-u', '--user', help='Nessus user instead of API key (password prompt will occur)',default=kullanici)
args = parser.parse_args()
if kullanici:
args.user = kullanici
# Get keys
keys = None
password = None
if args.keyfile:
if os.path.isfile(args.keyfile):
try:
f_key = open(args.keyfile, 'r')
try:
keys = json.loads(f_key.read())
except ValueError as err:
print_err(str(err))
print_err('could parse read key file "' + args.keyfile + '".', True)
f_key.close()
except IOError:
print_err('could not read key file "' + args.keyfile + '".', True)
else:
print_err('"' + args.keyfile + '" is not a valid file.', True)
elif kullanici:
password = parola
elif args.user:
password = getpass.getpass()
else:
parser.error('No action taken, either a key file or user must be provided')
if args.capath and not os.path.isdir(args.capath):
print_err('CA path "' + args.capath + '" not found.', True)
if args.format == "db" and args.dbpasswd is None:
print_err('Format is db but no exported db password was specified, use --dbpasswd to specify', True)
nessus_url = "https://" + args.server + ":" + str(args.port)
insecure = args.insecure
localhost = args.server == 'localhost' or args.server[:4] == '127.' or args.server == '::1'
# allow localhost connections to proceed without warning, but warn otherwise if CA not set
if not args.capath:
if localhost:
insecure = True
elif not insecure:
# warn if user hasn't supplied a CA Path, but might expect security or bump into TLS errors later
print(
'WARNING: No CA path explicitly set. Connection to ' + nessus_url + ' could fail due to TLS/SSL server authentication')
scanner = None
if keys:
scanner = ness6rest.Scanner(url=nessus_url, api_akey=keys['accessKey'], api_skey=keys['secretKey'],
insecure=insecure, ca_bundle=args.capath)
elif password:
scanner = ness6rest.Scanner(url=nessus_url, login=args.user, password=password, insecure=insecure,
ca_bundle=args.capath)
else:
print_err('Failed to understand API key or password (this is probably a script BUG)', True)
# Get all reports
if scanner:
scanner.action(action='scans', method='get')
folders = scanner.res['folders']
#folders = [{'name': 'My Scans', 'unread_count': 0, 'default_tag': 1, 'custom': 0, 'id': 3, 'type': 'main'}]
scans = scanner.res['scans']
# create scan subfolders
for f in folders:
if not os.path.exists(f['name']):
if f['type'] == 'trash':
if args.trash:
os.mkdir(f['name'])
else:
os.mkdir(f['name'])
# try download and save scans into each folder the belong to
for s in scans:
scanner.scan_name = s['name']
scanner.scan_id = s['id']
folder_name = next(f['name'] for f in folders if f['id'] == s['folder_id'])
folder_type = next(f['type'] for f in folders if f['id'] == s['folder_id'])
# skip trash items?
if folder_name != 'My Scans' and not args.trash:
continue
if s['status'] == 'completed':
file_name = '%s_%s.%s' % (scanner.scan_name, scanner.scan_id, args.format)
file_name = file_name.replace('\\', '_')
file_name = file_name.replace('/', '_')
file_name = file_name.strip()
relative_path_name = folder_name + '/' + file_name
# PDF not yet supported
# python API wrapper nessrest returns the PDF as a string object instead of a byte object, making writing and correctly encoding the file a chore...
# other formats can be written out in text mode
file_modes = 'wt'
# DB is binary mode
if args.format == "db":
file_modes = 'wb'
elif args.format == 'nessus':
file_modes = 'wb'
with io.open(relative_path_name, file_modes) as fp:
if args.format != "db":
fp.write(scanner.download_scan(export_format=args.format))
else:
fp.write(scanner.download_scan(export_format=args.format, dbpasswd=args.dbpasswd))
else:
print_err('Failed to use scanner at ' + nessus_url + '.', True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment