Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 135 additions & 49 deletions autoNessus.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
# Email: grandy[at]redteamsecure.com #
# #
########################################
from datetime import datetime

try:import requests
except: print('Need to install the Requests module before execution'); exit()
try:
import requests
except:
print('Need to install the Requests module before execution')
exit()
import json
import sys
import argparse
Expand All @@ -38,25 +42,30 @@
group.add_argument('-sR', '--resume', dest='resume_scan_id', type=str, help='Resume a specified scan using scan id')
group.add_argument('-pS', '--pause', dest='pause_scan_id', type=str, help='Pause a specified scan using scan id')
group.add_argument('-sP', '--stop', dest='stop_scan_id', type=str, help='Stop a specified scan using scan id')
group.add_argument('-e', '--exportid', dest='exportid', type=str, help='Export a specified scan using scan id')
group.add_argument('-eA', '--exportall', dest='export_all_scans', action='store_true', help='Export all scans.')
parser.add_argument('-d', '--fromdate', dest='minimumdate', type=str, help='Consider only Scans from Date (format: '
'YYYY.MM.DD)')

args = parser.parse_args()

if not len(sys.argv) > 1:
parser.print_help()
print
exit()

# Specify credentials for Nessus and initialize vars
url = 'https://localhost:8834'
url = ''
verify = False
token = ''
username = 'xxxxx'
password = 'xxxxx'
username = ''
password = ''


class create_menu:
'''This is used to build an instance of the menu object
and can be called from the main program to instantiate the menu
with passed variables.'''

def __init__(self, menu, text, other):
self.text = text
self.menu = menu
Expand All @@ -66,15 +75,19 @@ def __init__(self, menu, text, other):
option_length_menu = len(menu)
option_length_text = len(text)
if self.other != 'Null':
print('%s' + (20-option_length_menu) * ' ' + ' : %s' + (15-option_length_text)*' ' + ': %s') %(menu,text,other)
print(
'%s' + (20 - option_length_menu) * ' ' + ' : %s' + (15 - option_length_text) * ' ' + ': %s') % (
menu, text, other)

else:
print('%s' + (15-option_length_menu) * ' ' + ' : %s') %(menu,text)
print('%s' + (15 - option_length_menu) * ' ' + ' : %s') % (menu, text)
return


def build_url(resource):
return '{0}{1}'.format(url, resource)


def connect(method, resource, data=None, params=None):
"""
Send a request
Expand All @@ -100,7 +113,7 @@ def connect(method, resource, data=None, params=None):
# Exit if there is an error.
if r.status_code != 200:
e = r.json()
print e['error']
print(e['error'])
sys.exit()

# When downloading a scan we need the raw contents not the JSON data.
Expand Down Expand Up @@ -133,20 +146,36 @@ def get_policies():
return dict((p['title'], p['uuid']) for p in data['templates'])


def get_scans():
def get_scans(mindate=""):
"""
Get history ids
Create a dictionary of scans and uuids
"""

status_dict = {}
name_dict = {}
data = connect('GET', '/scans/')
params = {}
timestamp = 0

# check date limit
if mindate is not None:
try:
scandate = datetime.strptime(mindate, "%Y.%m.%d").timetuple()
timestamp = int(time.mktime(scandate))
params = {"last_modification_date": timestamp}
print(params)
except Exception as e:
print('Invalid date format: {0}.'.format(e))
logout()

data = connect('GET', '/scans/', params)
print
for p in data['scans']:
status_dict[p['id']] = p['status']
name_dict[p['id']] = p['name']
#status_dict = dict((p['name'], p['status']) for p in data['scans'])
#id_dict = dict((b['name'], b['id']) for b in data['scans'])
if p['last_modification_date'] >= timestamp: # done this since params is NOT working here
status_dict[p['id']] = p['status']
name_dict[p['id']] = p['name']
# status_dict = dict((p['name'], p['status']) for p in data['scans'])
# id_dict = dict((b['name'], b['id']) for b in data['scans'])

return status_dict, name_dict

Expand All @@ -160,14 +189,14 @@ def get_history_ids(sid):
"""
data = connect('GET', '/scans/{0}'.format(sid))
temp_hist_dict = dict((h['history_id'], h['status']) for h in data['history'])
temp_hist_dict_rev = {a:b for b,a in temp_hist_dict.items()}
temp_hist_dict_rev = {a: b for b, a in temp_hist_dict.items()}
try:
for key,value in temp_hist_dict_rev.items():
print key
print value
for key, value in temp_hist_dict_rev.items():
print(key)
print(value)
except:
pass
#return dict((h['uuid'], h['history_id']) for h in data['history'])
# return dict((h['uuid'], h['history_id']) for h in data['history'])


def get_scan_history(sid, hid):
Expand All @@ -185,10 +214,10 @@ def get_status(sid):
# Get the status of a scan by the sid.
# Print out the scan status

time.sleep(3) # sleep to allow nessus to process the previous status change
time.sleep(3) # sleep to allow nessus to process the previous status change
temp_status_dict, temp_name_dict = get_scans()
print '\nScan Name Status '
print '---------------------------------------'
print('\nScan Name Status ')
print('---------------------------------------')
for key, value in temp_name_dict.items():
if str(key) == str(sid):
create_menu(value, temp_status_dict[key], 'Null')
Expand All @@ -200,21 +229,61 @@ def launch(sid):
data = connect('POST', '/scans/{0}/launch'.format(sid))
return data['scan_uuid']


def pause(sid):
# Pause the scan specified by the sid.
connect('POST', '/scans/{0}/pause'.format(sid))
return


def resume(sid):
# Resume the scan specified by the sid.
connect('POST', '/scans/{0}/resume'.format(sid))
return


def stop(sid):
# Resume the scan specified by the sid.
connect('POST', '/scans/{0}/stop'.format(sid))
return

# Strips invalid chars from filename
def clean_filename(filename):
invalid = '<>:"/\|?* '
for char in invalid:
filename = filename.replace(char, '_')
return filename

def export(sid, name):
# Export the scan specified by the sid.

# 1- Ask for the export
params = {'format': 'nessus'}
filetoken = connect('POST', '/scans/{0}/export'.format(sid), params)

# 2- Wait until the export is ready to be downloaded
fileready = "notready"
maxtries = 10
trying = 0
while fileready != "ready" and trying < maxtries:
trying += 1
response = connect('GET', '/tokens/{0}/status'.format(filetoken['token']))
fileready = response['status']
time.sleep(1)

# 3- Export is ready. Download the file
if fileready == "ready":
nome_arq = '{0} - {1}.nessus'.format(sid, name)

arquivo = open(clean_filename(nome_arq), mode='wb')
filecontents = connect('GET', '/tokens/{0}/download'.format(filetoken['token']))

arquivo.write(filecontents)
arquivo.close()

return


def logout():
# Logout of Nessus.
print('Logging Out...')
Expand All @@ -223,7 +292,6 @@ def logout():
exit()



if __name__ == '__main__':
print('Script started: ' + time.strftime('%m-%d-%y @ %H:%M:%S'))

Expand All @@ -232,38 +300,38 @@ def logout():
exit()

print('Logging in...')
try:token = login(username, password)
except: print('Unable to login :('); exit()
try:
token = login(username, password)
except:
print('Unable to login :(')
exit()
print('Logged in!\n\n')


###### Display all policies #######
###### Display all policies #######
if args.policy_list:
# If -p flag is specified, print the policy list and exit

print "Printing Policies \n\n"
print("Printing Policies \n\n")
policy_dict = get_policies()
print 'Policy Name UUID'
print '--------------------------------------------------'
for title,uuid in policy_dict.items():
create_menu(title,uuid, 'Null')

print('Policy Name UUID')
print('--------------------------------------------------')
for title, uuid in policy_dict.items():
create_menu(title, uuid, 'Null')

###### Display all scans #######
###### Display all scans #######
elif args.scan_list:
# If -l flag is specified, print the list of scans

temp_status_dict, temp_name_dict = get_scans()
print 'Scan Name Status ID'
print '-------------------------------------------------'
print('Scan Name Status ID')
print('-------------------------------------------------')

for status_id,status_value in temp_status_dict.items():
for status_id, status_value in temp_status_dict.items():
for name_id, name_value in temp_name_dict.items():
if status_id == name_id:
create_menu(name_value,status_value, status_id)
create_menu(name_value, status_value, status_id)


###### Start the scan #######
###### Start the scan #######
if args.start_scan_id:
# If -sS [scan_id] flag is passed, start the specified scan
start_id = args.start_scan_id
Expand All @@ -272,8 +340,9 @@ def logout():
# Grab the status of the scan and either resume or start based on status
for key, value in temp_name_dict.items():
if str(key) == str(start_id):
if temp_status_dict[key].lower() in ['stopped', 'completed' , 'aborted', 'canceled', 'on demand', 'empty']:
print('Launching Scan %s') %key
if temp_status_dict[key].lower() in ['stopped', 'completed', 'aborted', 'canceled', 'on demand',
'empty']:
print('Launching Scan %s') % key
launch(start_id)
elif temp_status_dict[key].lower() in ['running']:
print('Scan already running!')
Expand All @@ -286,7 +355,7 @@ def logout():
# Re-grab the scans to get the updated status
get_status(start_id)

###### Resume the scan #######
###### Resume the scan #######
if args.resume_scan_id:
# If -sR [scan_id] flag is passed, start the specified scan
start_id = args.resume_scan_id
Expand All @@ -296,7 +365,7 @@ def logout():
for key, value in temp_name_dict.items():
if str(key) == str(start_id):
if temp_status_dict[key].lower() in ['paused']:
print('Resuming Scan %s') %key
print('Resuming Scan %s') % key
resume(start_id)
elif temp_status_dict[key].lower() in ['running']:
print('Scan already running!')
Expand All @@ -309,7 +378,7 @@ def logout():
# Re-grab the scans to get the updated status
get_status(start_id)

###### Pause the scan #######
###### Pause the scan #######
elif args.pause_scan_id:
# If -pS [scan_id] flag is passed, pause the specified scan
pause_id = args.pause_scan_id
Expand All @@ -320,7 +389,7 @@ def logout():
print('Scan already paused!')
logout()
elif temp_status_dict[key].lower() in ['running']:
print('Pausing Scan %s') %key
print('Pausing Scan %s') % key
pause(pause_id)
else:
print('Scan unable to be paused')
Expand All @@ -329,7 +398,7 @@ def logout():
# Re-grab the scans to get the updated status
get_status(pause_id)

###### Stop the scan #######
###### Stop the scan #######
elif args.stop_scan_id:
# If -sP [scan_id] flag is passed, stop the specified scan

Expand All @@ -338,7 +407,7 @@ def logout():
for key, value in temp_name_dict.items():
if str(key) == str(stop_id):
if temp_status_dict[key].lower() in ['paused', 'running']:
print('Stopping Scan %s') %key
print('Stopping Scan %s') % key
stop(stop_id)
logout()
else:
Expand All @@ -347,3 +416,20 @@ def logout():

# Re-grab the scans to get the updated status
get_status(stop_id)

if args.exportid:
scanid = args.exportid
temp_status_dict, temp_name_dict = get_scans()
for key, value in temp_name_dict.items():
if str(key) == str(scanid):
print('Exporting Scan: {0}'.format(value))
export(scanid, value)

logout()
elif args.export_all_scans:
print('Minimum date: {0}'.format(args.minimumdate))
temp_status_dict, temp_name_dict = get_scans(mindate=args.minimumdate)
for id, nome in temp_name_dict.items():
print('Exporting Scan: {0}'.format(nome))
export(id, nome)