Home page logo
/

Script Format

NSE scripts consist of a handful of descriptive fields, a rule defining when the script should be executed, and an action function containing the actual script instructions. Values can be assigned to the descriptive fields just as you would assign any other Lua variables. Their names must be lowercase as shown in this section.

description Field

The description field describes what a script is testing for and any important notes the user should be aware of. Depending on script complexity, descriptions may vary in length from a few sentences to a few paragraphs. The first paragraph should be a brief synopsis of the script function suitable for stand-alone presentation to the user. Further paragraphs may provide much more script detail.

categories Field

The categories field defines one or more categories to which a script belongs (see the section called “Script Categories”). The categories are case-insensitive and may be specified in any order. They are listed in an array-style Lua table as in this example:

categories = {"default", "discovery", "safe"}

author Field

The author field contains the script authors' names and can also contain contact information (such as home page URLs). We no longer recommend including email addresses because spammers might scrape them from the NSEDoc web site. This optional field is not used by NSE, but gives script authors their due credit or blame.

license Field

Nmap is a community project and we welcome all sorts of code contributions, including NSE scripts. So if you write a valuable script, don't keep it to yourself! The optional license field helps ensure that we have legal permission to distribute all the scripts which come with Nmap. All of those scripts currently use the standard Nmap license (described in the section called “Nmap Copyright and Licensing”). They include the following line:

license = "Same as Nmap--See http://nmap.org/book/man-legal.html"

The Nmap license is similar to the GNU GPL. Script authors may use a BSD-style license (no advertising clause) instead if they prefer that.

dependencies Field

The dependencies field is an array containing the names of scripts that should run before this script, if they are also selected. This is used when one script can make use of the results of another. For example, most of the smb-* scripts depend on smb-brute, because the accounts found by smb-brute may allow the other scripts to get more information. Listing a script in dependencies doesn't cause that script to be run; it still has to be selected through the --script option or otherwise. dependencies merely forces an ordering among the scripts that are selected. This is an example of a dependencies table, from smb-os-discovery:

dependencies = {"smb-brute"}

The dependencies table is optional. NSE will assume the script has no dependencies if the field is omitted.

Dependencies establish an internal ordering of scripts, assigning each one a number called a runlevel[9]. When running your scripts you will see the runlevel (along with the total number of runlevels) of each grouping of scripts run in NSE's output:

NSE: Script scanning 127.0.0.1.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Script Scanning completed.

Rules

Nmap uses the script rules to determine whether a script should be run against a target. A script contains either a prerule function, which lets the script to be run during the Script Pre-scanning phase, or a portrule function, which governs which ports of a target the scripts may run against, or a hostrule function, which specifies that the script should be run only once against a target IP and only if the given conditions are met, or a postrule function, which lets the script to be run during the Script Post-scanning phase. A rule is a Lua function that returns either true or false. A script can have multiple rules functions in order to run at different script scan phases, and to share the same code. The script action function is only performed if the rule evaluates to true. Prerules and postrules do not accept arguments. Hostrules accept a host table as their argument and may test, for example, the IP address or hostname of the target. Portrules accept both host and port tables as arguments for any TCP or UDP port in the open, open|filtered, or unfiltered port states. Port rules generally test factors such as the port number, port state, or listening service name in deciding whether to run against a port. Example rules are shown in the section called “The Rule”. The current standard to choose between a prerule or a postrule is: if the script is doing host discovery or any other network operation then the prerule should be used. The postrule is reserved for data reporting and statistics gathering that were generated during the scan.

Action

The action is the heart of an NSE script. It contains all of the instructions to be executed when the script's prerule, portrule, hostrule or postrule triggers. It is a Lua function which accepts the same arguments as the rule and can return either nil or a string. If a string is returned by a service script, the string and script's filename are printed in the Nmap port table output. A string returned by a host script is printed below the port table. No output is produced if the script returns nil. For an example of an NSE action refer to the section called “The Action”.

Environment Variables

Each script has its own set of environment variables:

SCRIPT_PATH

The script path.

SCRIPT_NAME

The script name. This variable can be used in debug output.

SCRIPT_TYPE

Since a script can have multiple rule functions, this environment variable will show which rule has activated the script, this would be useful if the script wants to share some code between different Script Scan phases. It will take one of these four string values: "prerule", "hostrule", "portrule" or "postrule".

This is an example of a debug code that uses the previous environment variables, followed by the output message, from dns-zone-transfer:

          stdnse.print_debug(3, "Skipping '%s' %s, 'dnszonetransfer.server' argument is missing.", SCRIPT_NAME, SCRIPT_TYPE)
        

          Initiating NSE at 15:31
          NSE: Skipping 'dns-zone-transfer' prerule, 'dnszonetransfer.server' argument is missing.
        



[9] Up through Nmap version 5.10BETA2, dependencies didn't exist and script authors had to set a runlevel field manually.

[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]