diff --git a/nse_main.lua b/nse_main.lua index a14696810..c6438b836 100644 --- a/nse_main.lua +++ b/nse_main.lua @@ -443,7 +443,7 @@ do co = co, env = env, identifier = tostring(co), - info = format("'%s' (%s)", self.short_basename, tostring(co)); + info = format("'%s' M:%s", self.id, match(tostring(co), "0x(.*)") , -1); parent = nil, -- placeholder script = self, type = script_type, @@ -466,7 +466,7 @@ do args = {n = select("#", ...), ...}, close_handlers = {}, co = co, - info = format("'%s' worker (%s)", self.short_basename, tostring(co)); + info = format("'%s' W:%s", self.id, match(tostring(co), "0x(.*)") , -1); parent = self, worker = true, }; @@ -905,6 +905,20 @@ local function run (threads_iter, hosts) rawset(stdnse, "base", function () return current and current.co; end); + rawset(stdnse, "gettid", function () + return current and current.identifier; + end); + rawset(stdnse, "getid", function () + return current and current.id; + end); + rawset(stdnse, "gethostport", function () + if current then + return current.host, current.port; + end + end); + rawset(stdnse, "isworker", function () + return current and current.worker; + end); while threads_iter and num_threads < CONCURRENCY_LIMIT do local thread = threads_iter() @@ -1344,6 +1358,10 @@ local function main (hosts, scantype) -- These functions do not exist until we are executing action functions. rawset(stdnse, "new_thread", nil) rawset(stdnse, "base", nil) + rawset(stdnse, "gettid", nil) + rawset(stdnse, "getid", nil) + rawset(stdnse, "gethostport", nil) + rawset(stdnse, "isworker", nil) for runlevel, scripts in ipairs(runlevels) do -- This iterator is passed to the run function. It returns one new script diff --git a/nselib/stdnse.lua b/nselib/stdnse.lua index 7e085d626..4ad0e9378 100644 --- a/nselib/stdnse.lua +++ b/nselib/stdnse.lua @@ -33,6 +33,7 @@ local max = math.max local format = string.format; local rep = string.rep +local match = string.match local concat = table.concat; local insert = table.insert; @@ -61,14 +62,72 @@ _ENV.sleep = nmap.socket.sleep; -- Prints a formatted debug message if the current debugging 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's string.format function. +-- 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's string.format function. +-- +-- If known, the output includes some context based information: the script +-- identifier and the target ip/port (if there is one). If the debug level is +-- at least 2, it also prints the base thread identifier and whether it is a +-- worker thread or the master thread. +-- -- @param level Optional debugging level. -- @param fmt Format string. -- @param ... Arguments to format. +function debug (level, fmt, ...) + local current = nmap.debugging() + local prefix = "[" + local id = getid() + if id then + prefix = prefix .. id + end + local host, port = gethostport() + if host and host.ip then + prefix = prefix .. " " .. host.ip + end + if port and port.number then + prefix = prefix .. ":" .. port.number + end + local tid = gettid() + local tid = match(tostring(tid), "0x(.*)") + local worker = isworker() + if current >= 2 and tid then + if worker then + prefix = prefix .. " W:" .. tid + else + prefix = prefix .. " M:" .. tid + end + end + prefix = prefix .. "] " + if type(level) == "number" then + if level <= current then + if prefix ~= "[] " then + nmap.log_write("stdout", prefix..format(fmt, ...)) + else + nmap.log_write("stdout", format(fmt, ...)) + end + end + elseif 1 <= current then + -- level is fmt and fmt is first argument + if prefix ~= "[] " then + nmap.log_write("stdout", prefix..format(level, fmt, ...)) + else + nmap.log_write("stdout", format(level, fmt, ...)) + end + end +end + +--Aliases for particular debug levels +function debug1 (...) return stdnse.debug(1, ...) end +function debug2 (...) return stdnse.debug(2, ...) end +function debug3 (...) return stdnse.debug(3, ...) end +function debug3 (...) return stdnse.debug(4, ...) end +function debug5 (...) return stdnse.debug(5, ...) end + +--- +-- Deprecated version of debug(), kept for now to prevent the script id from being +-- printed twice. Scripts should use debug() and not pass SCRIPT_NAME print_debug = function(level, fmt, ...) local l, d = tonumber(level), nmap.debugging(); if l and l <= d then @@ -77,19 +136,68 @@ print_debug = function(level, fmt, ...) nmap.log_write("stdout", format(level, fmt, ...)); end end - + --- -- Prints a formatted verbosity 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 verbosity level +-- necessary to print the message (it defaults to 1 if omitted). All remaining +-- arguments are processed with Lua's string.format function. +-- +-- If known, the output includes some context based information: the script +-- identifier. If the verbosity level is at least 2, it also prints the target +-- ip/port (if there is one) -- --- This is a convenience wrapper around --- nmap.log_write. The first optional numeric --- argument, level, is used as the verbosity level necessary --- to print the message (it defaults to 1 if omitted). All remaining arguments --- are processed with Lua's string.format function. -- @param level Optional verbosity level. -- @param fmt Format string. -- @param ... Arguments to format. +function verbose (level, fmt, ...) + local current = nmap.verbosity() + local prefix = "[" + local id = getid() + if id then + prefix = prefix .. id + end + if current >= 2 then + local host, port = gethostport() + if host and host.ip then + prefix = prefix .. " " .. host.ip + end + if port and port.number then + prefix = prefix .. ":" .. port.number + end + end + prefix = prefix .. "] " + if type(level) == "number" then + if level <= current then + if prefix ~= "[] " then + nmap.log_write("stdout", prefix..format(fmt, ...)) + else + nmap.log_write("stdout", format(fmt, ...)) + end + end + elseif 1 <= current then + -- level is fmt and fmt is first argument + if prefix ~= "[] " then + nmap.log_write("stdout", prefix..format(level, fmt, ...)) + else + nmap.log_write("stdout", format(level, fmt, ...)) + end + end +end + +--Aliases for particular verbosity levels +function verbose1 (...) return stdnse.verbose(1, ...) end +function verbose2 (...) return stdnse.verbose(2, ...) end +function verbose3 (...) return stdnse.verbose(3, ...) end +function verbose4 (...) return stdnse.verbose(4, ...) end +function verbose5 (...) return stdnse.verbose(5, ...) end + +--- +-- Deprecated version of verbose(), kept for now to prevent the script id from being +-- printed twice. Scripts should use verbose() and not pass SCRIPT_NAME print_verbose = function(level, fmt, ...) local l, d = tonumber(level), nmap.verbosity(); if l and l <= d then @@ -99,7 +207,6 @@ print_verbose = function(level, fmt, ...) end end - --- Join a list of strings with a separator string. -- -- This is Lua's table.concat function with the parameters diff --git a/scripts/http-default-accounts.nse b/scripts/http-default-accounts.nse index 07108c79f..be47c328b 100644 --- a/scripts/http-default-accounts.nse +++ b/scripts/http-default-accounts.nse @@ -148,7 +148,7 @@ local function load_fingerprints(filename, cat) -- Check if fingerprints are cached if(nmap.registry.http_default_accounts_fingerprints ~= nil) then - stdnse.print_debug(1, "%s: Loading cached fingerprints", SCRIPT_NAME) + stdnse.debug(1, "Loading cached fingerprints") return nmap.registry.http_default_accounts_fingerprints end @@ -160,11 +160,11 @@ local function load_fingerprints(filename, cat) end -- Load the file - stdnse.print_debug(1, "%s: Loading fingerprints: %s", SCRIPT_NAME, filename_full) + stdnse.debug(1, "Loading fingerprints: %s", filename_full) local env = setmetatable({fingerprints = {}}, {__index = _G}); file = loadfile(filename_full, "t", env) if( not(file) ) then - stdnse.print_debug(1, "%s: Couldn't load the file: %s", SCRIPT_NAME, filename_full) + stdnse.debug(1, "Couldn't load the file: %s", filename_full) return false, "Couldn't load fingerprint file: " .. filename_full end file() @@ -238,7 +238,7 @@ action = function(host, port) -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests local _, http_status, _ = http.identify_404(host,port) if ( http_status == 200 ) then - stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number) + stdnse.debug(1, "Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", host.ip, port.number) return nil end @@ -247,14 +247,14 @@ action = function(host, port) if(not(status)) then return stdnse.format_output(false, fingerprints) end - stdnse.print_debug(1, "%s: %d fingerprints were loaded", SCRIPT_NAME, #fingerprints) + stdnse.debug(1, "%d fingerprints were loaded", #fingerprints) --Format basepath: Removes or adds slashs basepath = format_basepath(basepath) -- Add requests to the http pipeline requests = {} - stdnse.print_debug(1, "%s: Trying known locations under path '%s' (change with '%s.basepath' argument)", SCRIPT_NAME, basepath, SCRIPT_NAME) + stdnse.debug(1, "Trying known locations under path '%s' (change with '%s.basepath' argument)", basepath, SCRIPT_NAME) for i = 1, #fingerprints, 1 do for j = 1, #fingerprints[i].paths, 1 do requests = http.pipeline_add(basepath .. fingerprints[i].paths[j].path, nil, requests, 'GET') @@ -278,7 +278,7 @@ action = function(host, port) for i, fingerprint in ipairs(fingerprints) do local credentials_found = false - stdnse.print_debug(1, "%s: Processing %s", SCRIPT_NAME, fingerprint.name) + stdnse.debug(1, "Processing %s", fingerprint.name) for _, probe in ipairs(fingerprint.paths) do if (results[j] and not(credentials_found)) then @@ -289,12 +289,12 @@ action = function(host, port) or fingerprint.target_check(host, port, path, results[j])) then for _, login_combo in ipairs(fingerprint.login_combos) do - stdnse.print_debug(2, "%s: Trying login combo -> %s:%s", SCRIPT_NAME, login_combo["username"], login_combo["password"]) + stdnse.debug(2, "Trying login combo -> %s:%s", login_combo["username"], login_combo["password"]) --Check default credentials if( fingerprint.login_check(host, port, path, login_combo["username"], login_combo["password"]) ) then --Valid credentials found - stdnse.print_debug(1, "%s:[%s] valid default credentials found.", SCRIPT_NAME, fingerprint.name) + stdnse.debug(1, "[%s] valid default credentials found.", fingerprint.name) output_lns[#output_lns + 1] = string.format("[%s] credentials found -> %s:%s Path:%s", fingerprint.name, login_combo["username"], login_combo["password"], path) -- Add to http credentials table