1. Introduction

We all know what Nmap is and what we can do with it, but for those of you who don’t, here’s a short overview. Nmap is an open source security scanner that can scan for open ports and also do other functions as well, such as auditing the operating system, detecting the application version, etc.

However, we often forget about the most powerful feature of Nmap scanner. We’ve not talking about host discovery, operating system enumeration, report generation or firewall evasion. We’re also not talking about Zenmap, which is a graphical user interface for Nmap. What we are talking about is the Nmap scripting engine. The Nmap scripting engine allows us to write scripts that we can use with Nmap to automate any task. When running these scripts, we can expect them to be quite powerful, since they are using the underlying Nmap software program that is famous for speed and efficiency.

2. The Nmap Scripting Engine (NSE)

Before diving straight into the NSE, we’ll say a few words about what NSE can do. We need to mention that NSE is capable of performing a wide variety of tasks. It can discover the devices on the network, scan for open ports, run a whois query, and more. It can scan a network to discover a newly disclosed vulnerability and while it isn’t as good as a vulnerability scanner that was written for that sole purpose, it gets the job done. It can even be used to actually exploit the vulnerability rather than just detect it.

The NSE scripts are written in a programming language called LUA. The scripts can be run with the command below:

# nmap -sC
# nmap --script

The -sC option enables the most common scripts, while we can choose the scripts to run with the –script option. The –script option takes comma-separated values as arguments which specify the scripts to be run upon starting Nmap. We don’t necessarily need to specify the script names, but we can specify the following: filenames, categories and directory names.

The Nmap main page contains the following regarding the Nmap scripting engine commands:

           SCRIPT SCAN:
             -sC: equivalent to --script=default
             --script=:  is a comma separated list of
                      directories, script-files or script-categories
             --script-args=: provide arguments to scripts
             --script-trace: Show all data sent and received
             --script-updatedb: Update the script database.

We already mentioned the -sC and –script command, but there are others as well. The –scripts-args command provides the arguments to each of the scripts, while the –script-trace command is used for debugging purposes to show all sent and received data. The –script-updatedb command is used to update the script database, which is needed if we added/removed a script or if we changed the categories. We must also mention that script scanning is automatically done if we pass the option -A (aggressive scan) to the Nmap command. There’s also a –script-help command that displays the help page of the script.

There are multiple commands we can use in combination with script scanning. Normally, Nmap first discovers if ports are online, or else it will run a port scan now and then to discover open ports on the active targets. To disable host discovery, we can use the -Pn option. To disable port scanning, we can use the -sn option.

To run a script without host or port discovery, run the command below (every host is assumed to be up):

Want to learn more?? The InfoSec Institute CISSP Training course trains and prepares you to pass the premier security certification, the CISSP. Professionals that hold the CISSP have demonstrated that they have deep knowledge of all 10 Common Body of Knowledge Domains, and have the necessary skills to provide leadership in the creation and operational duties of enterprise wide information security programs.

InfoSec Institute's proprietary CISSP certification courseware materials are always up to date and synchronized with the latest ISC2 exam objectives. Our industry leading course curriculum combined with our award-winning CISSP training provided by expert instructors delivers the platform you need in order to pass the CISSP exam with flying colors. You will leave the InfoSec Institute CISSP Boot Camp with the knowledge and domain expertise to successfully pass the CISSP exam the first time you take it. Some benefits of the CISSP Boot Camp are:

  • Dual Certification - CISSP and ISSEP/ISSMP/ISSAP
  • We have cultivated a strong reputation for getting at the secrets of the CISSP certification exam
  • Our materials are always updated with the latest information on the exam objectives: This is NOT a Common Body of Knowledge review-it is intense, successful preparation for CISSP certification.
  • We focus on preparing you for the CISSP certification exam through drill sessions, review of the entire Common Body of Knowledge, and practical question and answer scenarios, all following a high-energy seminar approach.
# nmap -sC -Pn -sn

2.1. Script Categories

Each NSE script belongs to a category based on what it does. Current categories are the following:

- auth: scripts that work with authentication credentials

- broadcast: scripts that discover active hosts by broadcasting on a local network and adding them to a target list

- brute: scripts that brute force the credentials of the remote service

- default: scripts that are automatically run with -sC or -A options

- discovery: scripts that try to acquire more information about the target network

- dos: scripts that may crash the target application and therefore cause a denial of service to the target

- exploit: scripts that may be able to exploit the target application

- external: scripts that send data to a third party server over the network (whois)

- fuzzer: scripts that send invalid random data to the target to find undiscovered bugs

- intrusive: scripts that can cause the target to fail

- malware: scripts that test whether the target is infected by malware or backdoors

- safe: scripts that can be run safely, so they will not crash a server

- version: scripts that can determine the version of the application running on a target (they are run only when -sV option is specified)

- vuln: scripts that can check whether the target is vulnerable to specific attacks

An example of running a script scan using the default script scan against the target www.google.com is shown below:

 nmap --script=default www.google.com

Starting Nmap 5.51 (http://nmap.org) at 2012-09-26 00:16 CEST
Nmap scan report for www.google.com (173.194.35.147)
Host is up (0.059s latency).
Other addresses for www.google.com (not scanned): 173.194.35.145 173.194.35.148 173.194.35.144 173.194.35.146
rDNS record for 173.194.35.147: muc03s01-in-f19.1e100.net
Not shown: 998 filtered ports
PORT  STATE SERVICE
80/tcp  open  http
|_http-methods: No Allow or Public header in OPTIONS response (status code 405)
| http-robots.txt: 245 disallowed entries (15 shown)
| /search /sdch /groups /images /catalogs /catalogues
| /news /nwshp /setnewsprefs? /index.html? /? /?hl=*&
|_/addurl/image? /pagead/ /relpage/
| http-title: 302 Moved
|_Did not follow redirect to http://www.google.si/
|_http-favicon:
443/tcp open  https
|_http-methods: No Allow or Public header in OPTIONS response (status code 405)
| http-robots.txt: 245 disallowed entries (15 shown)
| /search /sdch /groups /images /catalogs /catalogues
| /news /nwshp /setnewsprefs? /index.html? /? /?hl=*&
|_/addurl/image? /pagead/ /relpage/
| http-title: 302 Moved
|_Did not follow redirect to https://www.google.si/
|_http-favicon:

Nmap done: 1 IP address (1 host up) scanned in 7.22 seconds

We can see that there are multiple IP addresses for the domain name www.google.com and that we’re scanning only one of them, 173.194.35.147. Nmap scanned 1000 ports, 998 of which are filtered and two of which are opened: port 80 and port 443.

Nmap also performed a number of additional scans when determining the open ports. We can see that it first sent the “OPTIONS / HTTP/1.0″ request to the web server on both ports and received that the command OPTIONS is not allowed and it can’t be executed. Afterwards, it checked the contents of the robots.txt file that contained 15 entries, which are also listed. It did exactly the same scans for port 80 and port 443, since they are both running HTTP (except 443 is encrypted HTTP).

2.2. The NSE Script API

First, we must be aware that the NSE script is written in LUA. To use Nmap features in the LUA NSE script, there is an Nmap API accessible under the Nmap namespace, which we can use to call functions and access Nmap resources.

When beginning to write NSE scripts, there are quite a few variables that we can define in the beginning of the script to better describe it in detail. An example of the description, author, license, categories and action fields is presented below (this is taken from the banner script accessible here).

description = [[
A simple banner grabber which connects to an open TCP port and prints out anything sent by the listening service within five seconds.

The banner will be truncated to fit into a single line, but an extra line may be printed for every increase in the level of verbosity requested on the command line.
]]

author = "jah"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}

action = function( host, port )
    local out = grab_banner(host, port)
    return output( out )
end

We can see that the description field provides a description about what the script does, the author specifies the author of the script, etc. The following fields are available when writing NSE scripts:

- description: describes what the script does.

- categories: categorizes the script into the predefined categories.

- author: displays the scripts’ authors.

- license: displays the license the script was published under.

- dependencies: lists the dependencies as an array containing the names of scripts that need to be run before this script. The dependencies just force the ordering when running the scripts specified with –script option, and it doesn’t actually run the scripts.

- rules: defines the rules that are used to determine whether the script will be run against the target. Each rule must return either true or false and the action is only performed if the rule is evaluated to be true. A script must use one of the functions below to determine whether the rule has evaluated to true or not: prerule, hostrule, portrule or postrule. The prerule script is run before any hosts are scanned, while hostrule and portrule are run after each batch of hosts is scanned and then the postrule is run after all of the hosts have been scanned. Any data activity should be done in a prerule, while the postrule should be used for reporting. An example of a portrule taken from the previous banner example is below:

---
-- Script is executed for any TCP port.
portrule = function( host, port )
    return port.protocol == "tcp"
end

- action: defines a function to be run when the script’s prerule, portrule, hostrule or postrule is evaluated to true. The action function accepts the same arguments as the rule and returns a table of name-value pairs, a string or a nil (which is automatically parsed when being written to screen). Again, let’s take an example from the previous banner script, which defines the action as can be seen in the output below:

---
-- Grabs a banner and outputs it nicely formatted.
action = function( host, port )
    local out = grab_banner(host, port)
    return output( out )
end

Each script also has three environment variables local to the script. The SCRIPT_PATH specifies the path of the script, the SCRIPT_NAME specifies the name of the script and the SCRIPT_TYPE specifies the rule that activated the script. Those variables are automatically created when the script is run and we can use the variables in our script normally.

There are also a bunch of NSE libraries, which can be included and used just by requiring them in the NSE script LUA code. The libraries provide a powerful mechanism, since they can greatly enhance the power of an Nmap script with ease. All of the modules are shown on this web page: http://nmap.org/book/nse-library.html.

3. Conclusion

We’ve looked at the basics that we need to know when writing Nmap NSE scripts. In the next tutorial, we’ll take a look at the Nmap API and write a basic NSE script.

Further Resources:

Nmap’s commands and usage options