Library stdnse
Standard Nmap Scripting Engine functions.
This module contains various handy functions that are too small to justify modules of their own.
Copyright© Same as Nmap--See http://nmap.org/book/man-legal.html
Source: http://nmap.org/svn/nselib/stdnse.lua
Functions
| base () |
Returns the base coroutine of the running script. |
| format_difftime (t2, t1) |
Format the difference between times
t2 relative to t1; i.e., the
calculation is t2 minus t1.
|
| format_get_indent (indent, at_end) |
Get the indentation symbols at a given level. |
| format_output (status, data, indent) |
Takes a table of output on the commandline and formats it for display to the user. This is basically done by converting an array of nested tables into a string. In addition to numbered array elements, each table can have a 'name' and a 'warning' value. The 'name' will be displayed above the table, and 'warning' will be displayed, with a 'WARNING' tag, if and only if debugging is enabled. |
| make_buffer (socket, sep) |
Return a wrapper closure around a socket that buffers socket reads into chunks separated by a pattern. |
| new_thread (main, ...) |
This function allows you to create worker threads that may perform network tasks in parallel with your script thread. |
| print_debug (level, fmt, ...) |
Prints a formatted debug message if the current verbosity level is greater than or equal to a given level. |
| sleep (t) |
Sleeps for a given amount of time. |
| string_or_blank (string, blank) |
Either return the string itself, or return "<blank>" (or the value of the second parameter) if the string was blank or nil. |
| strjoin (delimiter, list) |
Join a list of strings with a separator string. |
| strsplit (pattern, text) |
Split a string at a given delimiter, which may be a pattern. |
| tobinary (n) |
Converts the given number, n, to a string in a binary number format (12 becomes "1100"). |
| tohex (s, options) |
Encode a string or number in hexadecimal (12 becomes "c", "AB" becomes "4142"). |
| tooctal (n) |
Converts the given number, n, to a string in an octal number format (12 becomes "14"). |
Functions
- base ()
-
Returns the base coroutine of the running script.
A script may be resuming multiple coroutines to facilitate its own collaborative multithreading design. Because there is a "root" or "base" coroutine that lets us determine whether the script is still active (that is, the script did not end, possibly due to an error), we provide this
stdnse.basefunction that will retrieve the base coroutine of the script. This base coroutine is the coroutine that runs the action function.The base coroutine is useful for many reasons but here are some common uses:
- We want to attribute the ownership of an object (perhaps a network socket) to a script.
- We want to identify if the script is still alive.
Return value:
coroutine Returns the base coroutine of the running script. - format_difftime (t2, t1)
-
Format the difference between times
t2andt1into a string in one of the forms (signs may vary):- 0s
- -4s
- +2m38s
- -9h12m34s
- +5d17h05m06s
- -2y177d10h13m20s
t2relative tot1; i.e., the calculation ist2minust1.Parameters
- t2:
- t1:
- format_get_indent (indent, at_end)
-
Get the indentation symbols at a given level.
Parameters
- indent:
- at_end:
- format_output (status, data, indent)
-
Takes a table of output on the commandline and formats it for display to the user. This is basically done by converting an array of nested tables into a string. In addition to numbered array elements, each table can have a 'name' and a 'warning' value. The 'name' will be displayed above the table, and 'warning' will be displayed, with a 'WARNING' tag, if and only if debugging is enabled.
Here's an example of a table:
local domains = {} domains['name'] = "DOMAINS" table.insert(domains, 'Domain 1') table.insert(domains, 'Domain 2') local names = {} names['name'] = "NAMES" names['warning'] = "Not all names could be determined!" table.insert(names, "Name 1") local response = {} table.insert(response, "Apple pie") table.insert(response, domains) table.insert(response, names) return stdnse.format_output(true, response)With debugging enabled, this is the output:
Host script results: | smb-enum-domains: | Apple pie | DOMAINS | Domain 1 | Domain 2 | NAMES (WARNING: Not all names could be determined!) |_ Name 1
Parameters
- status: A boolean value dictating whether or not the script succeeded. If status is false, and debugging is enabled, 'ERROR' is prepended to every line. If status is false and ebugging is disabled, no output occurs.
- data: The table of output.
- indent: Used for indentation on recursive calls; should generally be set to nil when callling from a script.
- make_buffer (socket, sep)
-
Return a wrapper closure around a socket that buffers socket reads into chunks separated by a pattern.
This function operates on a socket attempting to read data. It separates the data by
sepand, for each invocation, returns a piece of the separated data. Typically this is used to iterate over the lines of data received from a socket (sep = "\r?\n"). The returned string does not include the separator. It will return the final data even if it is not followed by the separator. Once an error or EOF is reached, it returnsnil, msg.msgis what is returned bynmap.receive_lines.Parameters
- socket: Socket for the buffer.
- sep: Separator for the buffered reads.
Return values:
- Data from socket reads or
nilon EOF or error. - Error message, as with
receive_lines.
- new_thread (main, ...)
-
This function allows you to create worker threads that may perform network tasks in parallel with your script thread.
Any network task (e.g.
socket:connect(...)) will cause the running thread to yield to NSE. This allows network tasks to appear to be blocking while being able to run multiple network tasks at once. While this is useful for running multiple separate scripts, it is unfortunately difficult for a script itself to perform network tasks in parallel. In order to allow scripts to also have network tasks running in parallel, we provide this function,stdnse.new_thread, to create a new thread that can perform its own network related tasks in parallel with the script.The script launches the worker thread by calling the
new_threadfunction with the parameters:- The main Lua function for the script to execute, similar to the script action function.
- The variable number of arguments to be passed to the worker's main function.
The
stdnse.new_threadfunction will return two results:- The worker thread's base (main) coroutine (useful for tracking status).
- A status query function (described below).
The status query function shall return two values:
- The result of coroutine.status using the worker thread base coroutine.
- The error object thrown that ended the worker thread or
nilif no error was thrown. This is typically a string, like most Lua errors.
Note that NSE discards all return values of the worker's main function. You must use function parameters, upvalues or environments to communicate results.
You should use the condition variable (
nmap.condvar) and mutex (nmap.mutex) facilities to coordinate with your worker threads. Keep in mind that Nmap is single threaded so there are no (memory) issues in synchronization to worry about; however, there is resource contention. Your resources are usually network bandwidth, network sockets, etc. Condition variables are also useful if the work for any single thread is dynamic. For example, a web server spider script with a pool of workers will initially have a single root html document. Following the retrieval of the root document, the set of resources to be retrieved (the worker's work) will become very large (an html document adds many new hyperlinks (resources) to fetch).Parameters
- main: The main function of the worker thread.
- ...: The arguments passed to the main worker thread.
Usage:
local requests = {"/", "/index.html", --[[ long list of objects ]]} function thread_main (host, port, responses, ...) local condvar = nmap.condvar(responses); local what = {n = select("#", ...), ...}; local allReqs = nil; for i = 1, what.n do allReqs = http.pGet(host, port, what[i], nil, nil, allReqs); end local p = assert(http.pipeline(host, port, allReqs)); for i, response in ipairs(p) do responses[#responses+1] = response end condvar "signal"; end function many_requests (host, port) local threads = {}; local responses = {}; local condvar = nmap.condvar(responses); local i = 1; repeat local j = math.min(i+10, #requests); local co = stdnse.new_thread(thread_main, host, port, responses, unpack(requests, i, j)); threads[co] = true; i = j+1; until i > #requests; repeat condvar "wait"; for thread in pairs(threads) do if coroutine.status(thread) == "dead" then threads[thread] = nil end end until next(threads) == nil; return responses; endReturn values:
- co The base coroutine of the worker thread.
- info A query function used to obtain status information of the worker.
- print_debug (level, fmt, ...)
-
Prints a formatted debug message if the current verbosity level is greater than or equal to a given level.
This is a convenience wrapper around
nmap.log_write. The first optional numeric argument,level, is used as the debugging level necessary to print the message (it defaults to 1 if omitted). All remaining arguments are processed with Lua'sstring.formatfunction.Parameters
- level: Optional debugging level.
- fmt: Format string.
- ...: Arguments to format.
- sleep (t)
-
Sleeps for a given amount of time.
This causes the program to yield control and not regain it until the time period has elapsed. The time may have a fractional part. Internally, the timer provides millisecond resolution.
Parameters
- t: Time to sleep, in seconds.
Usage:
stdnse.sleep(1.5)
- string_or_blank (string, blank)
-
Either return the string itself, or return "<blank>" (or the value of the second parameter) if the string was blank or nil.
Parameters
- string: The base string.
-
blank:
The string to return if
stringwas blank
Return value:
Eitherstringor, if it was blank,blank - strjoin (delimiter, list)
-
Join a list of strings with a separator string.
This is Lua's
table.concatfunction with the parameters swapped for coherence.Parameters
- delimiter: String to delimit each element of the list.
- list: Array of strings to concatenate.
Usage:
stdnse.strjoin(", ", {"Anna", "Bob", "Charlie", "Dolores"}) --> "Anna, Bob, Charlie, Dolores"Return value:
Concatenated string. - strsplit (pattern, text)
-
Split a string at a given delimiter, which may be a pattern.
Parameters
- pattern: Pattern that separates the desired strings.
- text: String to split.
Usage:
stdnse.strsplit(",%s*", "Anna, Bob, Charlie, Dolores") --> { "Anna", "Bob", "Charlie", "Dolores" }Return value:
Array of substrings without the separating pattern. - tobinary (n)
-
Converts the given number, n, to a string in a binary number format (12 becomes "1100").
Parameters
- n: Number to convert.
Return value:
String in binary format. - tohex (s, options)
-
Encode a string or number in hexadecimal (12 becomes "c", "AB" becomes "4142").
An optional second argument is a table with formatting options. The possible fields in this table are
separator: A string to use to separate groups of digits.group: The size of each group of digits between separators. Defaults to 2, but has no effect ifseparatoris not also given.
Parameters
- s: String or number to be encoded.
- options: Table specifiying formatting options.
Usage:
stdnse.tohex("abc") --> "616263" stdnse.tohex("abc", {separator = ":"}) --> "61:62:63" stdnse.tohex("abc", {separator = ":", group = 4}) --> "61:6263" stdnse.tohex(123456) --> "1e240" stdnse.tohex(123456, {separator = ":"}) --> "1:e2:40" stdnse.tohex(123456, {separator = ":", group = 4}) --> "1:e240"Return value:
String in hexadecimal format. - tooctal (n)
-
Converts the given number, n, to a string in an octal number format (12 becomes "14").
Parameters
- n: Number to convert.
Return value:
String in octal format.




