Attached is a new release of this script. Still no SSL support :( but the
config section is much improved.
--
~Jay
#!/usr/bin/python
####
# PROBLEM: Nessus stores a static list of plugins to use for a particular scan in the
.nessusrc
# file on the client (one line for every plugin). Since the plugins on the nessusd
server are
# updated almost daily, a client's .nessusrc file can become very out-of-date very
quickly.
# Currently, the only way to re-create an updated .nessusrc file is to run the Nessus
GUI client.
# This is not good for in a number of scenarios, like machines without a GUI
environment or
# doing unattended scans (i.e., from cron).
#
# SOLUTION: This script will connect to a nessusd server and dump its plugin list. We
will
# then enable/disable groups of plugins based on their family and write an up-to-date
.nessusrc
# file based on the plugins currently available on the nessusd server.
#
# This script has been tested on Linux and Mac OS X, using Nessus releases 1.0.10 and
1.1.12.
#
# * Note for Nessus 1.1.x: The client/server communications are always encrypted in
this, and
# probably latter, versions. This is a *good* thing overall. This is a bad thing for
this script
# since the telnet interface won't work that way. :) The kludge-fix for this is to
compile
# nessus-libraries with the "--disable-cipher" option. Hopefully we'll be able to add
SSL
# support to this script soon which would eliminate the need for this kludge.
#
# There are several problems with this script. First, it uses telnet to connect to the
nessusd
# server and authenticate. Therefore, everything done with this script is clear-text
and is
# a security risk (ironic, eh? :). Additionally, some plugins have their own
preferences
# defined in the .nessusrc file. However, this script *only* manipulates the
PLUGIN_SET portion
# of the .nessusrc file dynamically - everything else (including PLUGINS_PREFS) is
totally static
# as defined in the "HeaderText" or "FooterText" sections of this script. Therefore,
it is
# possible (likely) that this script will enable a new plugin but will *not* create
individual
# preferences for that plugin. The fix is to just run the Nessus GUI occasionally to
create
# the PLUGINS_PREFS, and then use those new settings in the HeaderText of this script.
# Again, ain't irony grand? :)
#
# I know there are ways to fix the above issues, so if someone would like to
contribute to this
# script that would be great. This script is my very first attempt at a non-Bash-shell
proggie,
# so please excuse any bad coding. Nonetheless, even with its shortcomings, this
script will
# allow you to update the plugins in your .nessusrc file without having to run the GUI
every day.
#
# *** Thank you to the entire Nessus team for all their hard work and a great
product! ***
#
# HISTORY:
# February 8, 2002 - Initial Release
# February 15, 2002 - Changed header/footer text to external template files
#
# This script is Copyright (C) 2002, Jay Jacobson <[EMAIL PROTECTED]>
####
import sys, time, telnetlib, string
NessusServer = 'localhost' # Name or IP of Nessus server to connect to.
NessusPort = 1241 # nessusd port - Should be either 1241 or
3001.
NTPversion = '< NTP/1.2 >' # Exact NTP version string as specified in NTP
docs.
NessusUser = 'test' # Username for nessusd connection.
NessusPass = 'password' # Password for nessusd connection username.
NessusdVer = '1.1' # Nessusd server version - either '1.0' or
'1.1'
# this will determine if we write plugin names
or ID#s.
##
# Name and path of final .nessusrc file to create
rcFile = '/tmp/.nessusrc'
####
# Must be either 'yes' or 'no' -- case and syntax must be exact
#
# Select which families of plugins to activate in the .nessusrc file. All plugins from
the
# selected family will be activated - even the "dangerous" ones.
####
FamBackdoor = 'yes' # Backdoors
FamCGI = 'yes' # CGI Abuses
FamDoS = 'yes' # Denial of Service
FamFinger = 'yes' # Finger Abuses
FamFirewall = 'yes' # Firewalls
FamFTP = 'yes' # FTP
FamShell = 'yes' # Gain a Shell Remotely
FamRoot = 'yes' # Gain Root Remotely
FamGeneral = 'yes' # General
FamMisc = 'yes' # Misc
FamNIS = 'yes' # NIS
FamScan = 'yes' # Port Scanners
FamFile = 'yes' # Remote File Access
FamRPC = 'yes' # RPC
FamSMTP = 'yes' # SMTP Problems
FamSNMP = 'yes' # SNMP
FamUseless = 'yes' # Useless Services
FamWindows = 'yes' # Windows
####
# Here we'll gather additional text to be added both before and after the generated
plugin set
# to the final .nessusrc file. This is necessary because this script is focused on
*only*
# updating the plugin sets and a complete .nessusrc file requires other stuff in it
too.
# You can probably just cut-n-paste the sections of your Nessus-GUI-created .nessusrc
file into
# the files listed here.
####
##
# Stuff to put at the beginning of the generated plugin set. Probably just cut-n-paste
from your
# Nessus-GUI-created .nessusrc file. The last line of this section should be:
begin(PLUGIN_SET)
HeaderFile = '/path/to/file/header-text'
##
# Stuff to put at the end of the generated plugin set. Probably just cut-n-paste from
your
# Nessus-GUI-created .nessusrc file. The first line (and possibly last/only line) of
this section
# should be: begin(PLUGIN_SET)
FooterFile = '/path/to/file/footer-text'
####
# This is the end of the configuration section - do not edit the stuff below here
####
##
# Create the HeaderText array
f=open(HeaderFile, 'r')
HeaderText = f.readlines()
f.close()
##
# Create the FooterText array
f=open(FooterFile, 'r')
FooterText = f.readlines()
f.close()
##
# Open the new .nessusrc file and write the HeaderText
f=open(rcFile, 'w')
for line in HeaderText [0:]:
f.write(line)
##
# Connect to the nessusd server
tn = telnetlib.Telnet(NessusServer, NessusPort)
##
# Send the login information
tn.write(NTPversion + "\n")
tn.read_until("User : ", 10)
tn.write(NessusUser + "\n")
tn.read_until("Password : ", 10)
tn.write(NessusPass + "\n")
##
# Read until end of nessusd plugin list or 300 seconds
ServerDump = tn.read_until("<|> SERVER\n", 300)
ServerString = string.split(ServerDump, "\n")
##
# Assign the nessusd version to the array position to use. For version 1.1, we'll use
# element [0] in the array, which is the plugin ID#. For version 1.0, we'll use
# element [1] in the array, which is the plugin name.
if NessusdVer == "1.1":
PlugName = 0
else:
PlugName = 1
##
# Kill the very first and last lines - they are just statements from nessusd
# Process all the other lines
for line in ServerString [1:-2]:
RawPlugin = string.split(line, " <|> ")
##
# The following line (commented out) will get the first family word, make all
# lowercase, and strip out trailing "." characters. However, this method also
# makes "gain shell" and "gain root" families look identical.
#
#LineFam = string.split(string.lower(string.split(RawPlugin [6]) [0]), ".")
[0]
##
# ...so, instead, we'll just lowercase everything and go with that.
# However, this method worries me because problems might occur if a non-alpha
# character (.,-_ or something) or typo slips into a plugin's family field.
LineFam = string.lower(RawPlugin [6])
if LineFam == "backdoors" and FamBackdoor == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "backdoors":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "cgi abuses" and FamCGI == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "cgi abuses":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "denial of service" and FamDoS == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "denial of service":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "finger abuses" and FamFinger == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "finger abuses":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "firewalls" and FamFirewall == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "firewalls":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "ftp" and FamFTP == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "ftp":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "gain a shell remotely" and FamShell == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "gain a shell remotely":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "gain root remotely" and FamRoot == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "gain root remotely":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "general" and FamGeneral == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "general":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "misc." and FamMisc == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "misc.":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "nis" and FamNIS == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "nis":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "port scanners" and FamScan == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "port scanners":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "remote file access" and FamFile == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "remote file access":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "rpc" and FamRPC == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "rpc":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "smtp problems" and FamSMTP == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "smtp problems":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "snmp" and FamSNMP == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "snmp":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "useless services" and FamUseless == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "useless services":
f.write(RawPlugin [PlugName] + ' = no\n')
if LineFam == "windows" and FamWindows == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "windows":
f.write(RawPlugin [PlugName] + ' = no\n')
##
# Write the FooterText and close the file
for line in FooterText [0:]:
f.write(line)
f.close()
##
# Close the connection to the nessusd server
tn.close()
#########
## EOF ##
#########