Nmap Security Scanner
*Intro
*Ref Guide
*Install Guide
*Download
*Changelog
*Book
*Docs
Security Lists
*Nmap Hackers
*Nmap Dev
*Bugtraq
*Full Disclosure
*Pen Test
*Basics
*More
Security Tools
*Pass crackers
*Sniffers
*Vuln Scanners
*Web scanners
*Wireless
*Exploitation
*Packet crafters
*More
Site News
Site Search:
Exploit World
Advertising
About/Contact
Credits
Sponsors:
edgeos network security services platform



Implementation Details

Now it is time to explore the NSE implementation details in depth. Understanding how NSE works is useful for designing efficient scripts and libraries. The canonical reference to the NSE implementation is the source code, but this section provides an overview of key details. It should be valuable to folks trying to understand and extend the NSE source code, as well as to script authors who want to better-understand how their scripts are executed.

Initialization Phase

During its initialization stage, Nmap loads the Lua interpreter and its provided libraries. These libraries are fully documented in the Lua Reference Manual. Here is a summary of the libraries, listed alphabetically by their namespace name:

debug

The debug library provides a low-level API to the Lua interpreter, allowing you to access functions along the execution stack, retrieve function closures and object metatables, and more.

io

The Input/Output library offers functions such as reading from files or from the output from programs you execute.

math

Numbers in Lua usually correspond to the double C type, so the math library provides access to rounding functions, trigonometric functions, random number generation, and more.

os

The Operating System library provides system facilities such as filesystem operations (including file renaming or removal and temporary file creation) and system environment access.

package

Among the functions provided by Lua's package-lib is require, which is used to load nselib modules.

string

The string library provides functions for manipulating Lua strings, including printf-style string formatting, pattern matching using Lua-style patterns, substring extraction, and more.

table

The table manipulation library is essential for operating on Lua's central data structure (tables).

In addition to loading the libraries provided by Lua, the nmap namespace functions are loaded. The search paths are the same directories that Nmap searches for its data files, except that the nselib directory is appended to each. At this stage any provided script arguments are stored inside the registry.

The next phase of NSE initialization is loading the selected scripts, based on the defaults or arguments provided to the --script option. The version category scripts are loaded as well if version detection was enabled. NSE first tries to interpret each --script argument as a category. This is done with a Lua C function in nse_init.cc named entry based on data from the script.db script categorization database. If the category is found, those scripts are loaded. Otherwise Nmap tries to interpret --script arguments as files or directories. If no files or directories with a given name are found in Nmap's search path, an error is raised and the Script Engine aborts.

If a directory is specified, all of the .nse files inside it are loaded. Each loaded file is executed by Lua. If a portrule is present, it is saved in the porttests table with a portrule key and file closure value. Otherwise, if the script has a hostrule, it is saved in the hosttests table in the same manner.

Matching Scripts with Targets

After initialization is finished, the hostrules and portrules are evaluated for each host in the current target group. The rules of every chosen script is tested against every host and (in the case of service scripts) each open and open|filtered port on the hosts. The combination can grow quite large, so portrules should be kept as simple as possible. Save any heavy computation for the script's action.

Next, a Lua thread is created for each of the matching script-target combinations. Each thread is stored with pertinent information such as the runlevel, target, target port (if applicable), host and port tables (passed to the action), and the script type (service or host script). The mainloop function then processes each runlevel grouping of threads in order.

Script Execution

Nmap performs NSE script scanning in parallel by taking advantage of Nmap's Nsock parallel I/O library and the Lua coroutines language feature. Coroutines offer collaborative multi-threading so that scripts can suspend themselves at defined points and allow other coroutines to execute. Network I/O, particularly waiting for responses from remote hosts, often involves long wait times, so this is when scripts yield to others. Key functions of the Nsock wrapper cause scripts to yield (pause). When Nsock finishes processing such a request, it makes a callback which causes the script to be pushed from the waiting queue back into the running queue so it can resume operations when its turn comes up again.

The mainloop function moves threads between the waiting and running queues as needed. A thread which yields is moved from the running queue into the waiting list. Running threads execute until they either yield, complete, or fail with an error. Threads are made ready to run (placed in the running queue) by calling process_waiting2running. This process of scheduling running threads and moving threads between queues continues until no threads exist in either queue.

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