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

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.
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: debugThe 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.
ioThe Input/Output library offers functions such as reading from files or from the output from programs you execute.
mathNumbers 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.
osThe
Operating System library provides system facilities such as filesystem operations (including file renaming or removal and temporary file creation) and system environment access.
packageAmong the functions provided by Lua's
package-lib is require, which is used to load nselib modules.
stringThe
string library provides functions for manipulating
Lua strings, including printf-style
string formatting, pattern matching using Lua-style patterns,
substring extraction, and more.
tableThe
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.
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. |
|