Writing Nessus Plugins

In a previous article, I showed you how to install and use the Nessus scanner. If the bundled security checks aren't enough for you, you can write your own Nessus plugins in NASL (Nessus Attack Scripting Language). This article demonstrates how to write your own custom vulnerability checks.

Why Write Your Own Vulnerability Checks?

Before you can patch systems affected by specific vulnerabilities, you must
first scan for them. There are commercial vulnerability scanners from vendors
who promise to update you with new plugins that scan for the latest
vulnerabilities, but in reality, many commercial scanner vendors do not release
these new checks until it's too late. In addition, your organization may know
of a vulnerability that exists in a homegrown application. In those cases,
you'll need to develop custom, in-house vulnerability checks.

Quite often,
organizations that need to scan their networks for the latest vulnerabilities
end up writing their own scanners from scratch, reinventing the wheel with
every new vulnerability found. Nessus provides an excellent framework in which
to write custom vulnerability checks, so there is no need to write scanners
from scratch. Besides, Nessus is free and open source, which makes the task
even easier.

The NASL Interpreter

With Nessus installed, take a look at the NASL scripts in the
/usr/local/lib/nessus/plugins/ directory. The Nessus server
executes these scripts when performing scans. To run a specific script on the
command line, use the NASL interpreter, nasl, with the
-t switch to signify the host to scan. For example, the
finger.nasl connects to a remote host on port 79 to check if
the fingerd daemon is running. To run this script against your own
host, run:

[notroot]$ nasl -t 127.0.0.1 finger.nasl

Writing a Plugin

Before we begin to write a Nessus plugin to scan for a vulnerability, we
need to define the vulnerability. We'll use the following definition. A homegrown web application serves the file /src/passwd.inc when a
client requests the URL http://host/src/passwd.inc. This file
contains usernames and hashes of passwords, so the server should not serve it. The following NASL script scans for this specific vulnerability:

When the Nessus server queries the plugin for summary information, the
description variable will hold a non-zero value. Therefore, we
define information about the plugin with description in this
case. The script_id function sets a unique ID for the plugin. Every plugin's value must be unique. In this case, we use a high number,
99999, to ensure a distinct value. The script_version function
sets the version number of the plugin. It is a good idea to update this number
to reflect the latest version of the plugin. The script_description function sets the description of the plugin. The Nessus client will show this description when the user queries a plugin.
Similarly, the script_summary function produces a summary
description of the plugin.

The script_category function sets the plugin's category as
required by Nessus. In our case, we have set it to ACT_GATHER_INFO
because the plugin gathers information about a remote service by checking for
the existence of the /src/passwd.inc file on a remote web server.
The script_copyright function sets author copyright
information.

Nessus can optimize scans, if you select the appropriate checkbox in the
Scan Option tab of the GUI client. When this option is enabled, Nessus scans
for vulnerabilities related to the applications running on the open ports of
the target host. We use the script_require_ports function to set
the port related to the vulnerability, which in our case is set
www, for HTTP traffic.

The functions described so far set various description values for the
plugin. Click on the appropriate plugin name from the list of plugins
displayed in the Plugins tab of the Nessus client to view them, as Figure 1
shows.

Figure 1. Plugin details.

The http_func.inc file contains a list of useful HTTP functions
for our convenience, so we include it using the include call.
Next, we define port to hold a value that is relevant to the web
server port number — 80. We use the is_cgi_installed
function to verify the existence of the file /src/passwd.inc. If
this file exists, is_cgi_installed returns true, and we call the
security_hole function to tell Nessus that we've found a security
hole.

Installing and Running the Plugin

Place the preceding script in the /usr/local/lib/nessus/plugins
directory. The script must end with the extension .nasl. Run the
Nessus GUI client and select the Plugins tab. Make sure that CGI Abuses is
selected. Highlight CGI Abuses and make sure the plugin with the name "Checks
for /src/passwd.inc" is enabled. If you have trouble finding the plugin, click
the Filter button and search for a filter with the ID of 99999.

To get a positive result from the plugin, you need to have a local web
server configured to serve the /src/passwd.inc file. If you have
an Apache server running on a host, create a file called
src/passwd in the web root of the web server. Now, enter the IP
address or hostname of the target web server in the Target Selection tab and
click the Start the Scan button. If everything goes well, Nessus will detect
and report our custom vulnerability, as shown in Figure 2.

Figure 2. Nessus report with output from our plugin.

Conclusion

That is all there is to writing a Nessus plugin using NASL! As you can see,
NASL is a language specifically tailored to make it easy to write vulnerability
checks. For more details on NASL, read the NASL reference manual (PDF).

Nitesh Dhanjani
is a well known security researcher, author, and speaker. Dhanjani has been invited to talk at various information security events such as the Black Hat Briefings, RSA, Hack in the Box, Microsoft Blue Hat, and OSCON.