Well, in an attempt to address this issue, I have written my very first
application. I am not, and have never claimed to be, a coder. Nonetheless,
the attached Python script will solve this issue. No, it's not perfect.
Yes, it does work.  :)   It has been tested with both the 1.0.10 and
1.1.12 releases.

The script is well commented and I would really be interested in any
feedback.

Renaud - feel free to throw this in a "contrib" (or simiar) folder with
Nessus if you like. Use it, abuse it, whatever. :)

Again, I'd really be interested in any feedback about this or
additions/patches to it. Thanks! :)

~Jay




On Tue, 12 Feb 2002, Renaud Deraison wrote:

> On Tue, Feb 12, 2002 at 02:09:47PM -0500, Dmitriy Kropivnitskiy wrote:
> > For my uses of nessus, making a separate interactive
> > CLI interface would not help things, since it will not
> > generate nessusrc automagically. My suggestion ( not sure
> >  if it is easily implementable ) would be to make a separate
> > program/script that would pull current .nessusrc in, pull current
> > plugin list, find differences and insert new plugins according to
> > some kind of a rule set.
>
> You can retrieve the list of plugins from the remote nessusd server
> by doing
>       nessus -pq nessusd_host 1241 login password
>
>
> That's a start - feel free to write the rest ;)
>
>                               -- Renaud
>

-- 
~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.
#
# 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
#
# 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.0'                 # 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 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)

HeaderText      = """
nessusd_host = NESSUSD.DOMAIN.COM
nessusd_user = NESSUSUSER
begin(SCANNER_SET)
 Ping the remote host = yes
 TCP Ping the remote host = yes
 TCP SYN scan = no
 FTP bounce scan = no
 Nmap tcp connect() scan = no
 Nmap = yes
 scan for LaBrea tarpitted hosts = no
end(SCANNER_SET)

begin(PLUGINS_PREFS)
 SMB use domain SID to enumerate users[entry]:Start UID : = 1000
 SMB use domain SID to enumerate users[entry]:End UID : = 1200
 Default accounts[entry]:Simultaneous connections : = 10
 Anonymous FTP enabled[entry]:FTP login : = ftp
 Anonymous FTP enabled[entry]:FTP password : = [EMAIL PROTECTED]
 ftp writeable directories[radio]:How to check if directories are writeable : = Trust 
the permissions (drwxrwx
--)
 Ping the remote host[entry]:TCP ping destination port : = 80
 Ping the remote host[checkbox]:Do a TCP ping = yes
 Ping the remote host[checkbox]:Do an ICMP ping = yes
 Ping the remote host[entry]:Number of retries (ICMP) : = 10
 Nmap[radio]:TCP scanning technique : = connect()
 Nmap[checkbox]:UDP port scan = no
 Nmap[checkbox]:RPC port scan = yes
 Nmap[checkbox]:Ping the remote host = no
 Nmap[checkbox]:Identify the remote OS = yes
 Nmap[checkbox]:Fragment IP packets (bypasses firewalls) = yes
 Nmap[checkbox]:Get Identd info = yes
 Nmap[checkbox]:Perform a fast scan = yes
 Nmap[checkbox]:Do not randomize the  order  in  which ports are scanned = yes
 Nmap[entry]:Source port : = any
 FTP bounce scan[entry]:FTP server to use : = localhost
end(PLUGINS_PREFS)

begin(SERVER_PREFS)
 max_threads = 20
 log_whole_attack = yes
 cgi_path = /cgi-bin
 port_range = 1-65535
 optimize_test = yes
 language = english
 track_iothreads = yes
 cookie_logpipe_suptmo = 2
 checks_read_timeout = 15
 delay_between_tests = 1
 plugins_timeout = 160
 host_expansion = ip
 ping_hosts = no
 reverse_lookup = no
end(SERVER_PREFS)

begin(RULES)
end(RULES)

begin(PLUGIN_SET)
"""

##
# ^^^ REMEMBER: The last line of the above section (before the closing """) 
# should be: begin(PLUGIN_SET)

##
# Stuff to put at the end of the generated plugin set. This is probably fine the way 
it is, but
# check your Nessus-GUI-created .nessusrc file just to be sure. The last line of this 
section
# should be: end(PLUGIN_SET)

FooterText      = """end(PLUGIN_SET)"""

##
# ^^^ REMEMBER: The last line of the above section (before the closing """) 
# should be: end(PLUGIN_SET)

####
# This is the end of the configuration section - do not edit the stuff below here
####

##
# Open the new .nessusrc file and write the HeaderText

f=open(rcFile, 'w')
f.write(HeaderText)

##
# 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

f.write(FooterText)
f.close()

##
# Close the connection to the nessusd server

tn.close()


#########
## EOF ##
#########

Reply via email to