Attached is the update-nessusrc.py script. The only change is adding
support for the new "Settings" family.
On a related note, is there any reliable way to get this type of new
information? The only reference to this new family that I've been able to
find is in the newsletter that was sent out earlier today. :)
--
~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
FamSettings = 'yes' # Settings
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 == "settings" and FamSettings == "yes":
f.write(RawPlugin [PlugName] + ' = yes\n')
elif LineFam == "settings":
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 ##
#########