mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Implements XML structured output. Closes #604
This commit is contained in:
@@ -40,8 +40,12 @@ o [NSE] Updated fingerprints for script http-default-accounts with 21 new
|
|||||||
fingerprints. 5 fingerprints have been broadened to cover more variants.
|
fingerprints. 5 fingerprints have been broadened to cover more variants.
|
||||||
[nnposter]
|
[nnposter]
|
||||||
|
|
||||||
o [NSE][GH#577] Script http-default-accounts now can test systems that return
|
o [NSE] Revised script http-default-accounts in several ways:
|
||||||
status 200 for non-existent pages. [nnposter]
|
- [GH#577] It can now can test systems that return status 200 for
|
||||||
|
non-existent pages. [nnposter]
|
||||||
|
- [GH#604] Implemented XML output. Layout of the classic text output has also
|
||||||
|
changed, including reporting blank usernames or passwords as "<blank>",
|
||||||
|
instead of just empty strings. [nnposter]
|
||||||
|
|
||||||
o [NSE][GH#573] Updated http.lua to allow processing of HTTP responses with
|
o [NSE][GH#573] Updated http.lua to allow processing of HTTP responses with
|
||||||
malformed header names. Such header lines are still captured in the rawheader
|
malformed header names. Such header lines are still captured in the rawheader
|
||||||
|
|||||||
@@ -44,9 +44,33 @@ This script was based on http-enum.
|
|||||||
-- nmap -p80 --script http-default-accounts host/ip
|
-- nmap -p80 --script http-default-accounts host/ip
|
||||||
--
|
--
|
||||||
-- @output
|
-- @output
|
||||||
-- PORT STATE SERVICE REASON
|
-- PORT STATE SERVICE
|
||||||
-- 80/tcp open http syn-ack
|
-- 80/tcp open http
|
||||||
-- |_http-default-accounts: [Cacti] credentials found -> admin:admin Path:/cacti/
|
-- | http-default-accounts:
|
||||||
|
-- | [Cacti] at /
|
||||||
|
-- | admin:admin
|
||||||
|
-- | [Nagios] at /nagios/
|
||||||
|
-- |_ nagiosadmin:CactiEZ
|
||||||
|
--
|
||||||
|
-- @xmloutput
|
||||||
|
-- <table key="Cacti">
|
||||||
|
-- <elem key="path">/</elem>
|
||||||
|
-- <table key="credentials">
|
||||||
|
-- <table>
|
||||||
|
-- <elem key="username">admin</elem>
|
||||||
|
-- <elem key="password">admin</elem>
|
||||||
|
-- </table>
|
||||||
|
-- </table>
|
||||||
|
-- </table>
|
||||||
|
-- <table key="Nagios">
|
||||||
|
-- <elem key="path">/nagios/</elem>
|
||||||
|
-- <table key="credentials">
|
||||||
|
-- <table>
|
||||||
|
-- <elem key="username">nagiosadmin</elem>
|
||||||
|
-- <elem key="password">CactiEZ</elem>
|
||||||
|
-- </table>
|
||||||
|
-- </table>
|
||||||
|
-- </table>
|
||||||
--
|
--
|
||||||
-- @args http-default-accounts.basepath Base path to append to requests. Default: "/"
|
-- @args http-default-accounts.basepath Base path to append to requests. Default: "/"
|
||||||
-- @args http-default-accounts.fingerprintfile Fingerprint filename. Default: http-default-accounts-fingerprints.lua
|
-- @args http-default-accounts.fingerprintfile Fingerprint filename. Default: http-default-accounts-fingerprints.lua
|
||||||
@@ -59,6 +83,12 @@ This script was based on http-enum.
|
|||||||
-- * changed category from safe to intrusive
|
-- * changed category from safe to intrusive
|
||||||
-- 2016-08-10 nnposter
|
-- 2016-08-10 nnposter
|
||||||
-- * added sharing of probe requests across fingerprints
|
-- * added sharing of probe requests across fingerprints
|
||||||
|
-- 2016-10-30 nnposter
|
||||||
|
-- * removed a limitation that prevented testing of systems returning
|
||||||
|
-- status 200 for non-existent pages.
|
||||||
|
-- 2016-12-01 nnposter
|
||||||
|
-- * implemented XML structured output
|
||||||
|
-- * changed classic output to report empty credentials as <blank>
|
||||||
---
|
---
|
||||||
|
|
||||||
author = {"Paulino Calderon <calderon@websec.mx>", "nnposter"}
|
author = {"Paulino Calderon <calderon@websec.mx>", "nnposter"}
|
||||||
@@ -212,15 +242,48 @@ local function format_basepath(basepath)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- register_http_credentials(username, password)
|
-- test_credentials(host, port, fingerprint, path)
|
||||||
-- Stores HTTP credentials in the registry. If the registry entry hasn't been
|
-- Tests default credentials of a given fingerprint against a given path.
|
||||||
-- initiated, it will create it and store the credentials.
|
-- Any successful credentials are registered in the Nmap credential repository.
|
||||||
-- @param login_username Username
|
-- @param host table as received by the scripts action method
|
||||||
-- @param login_password Password
|
-- @param port table as received by the scripts action method
|
||||||
|
-- @param fingerprint as defined in the fingerprint file
|
||||||
|
-- @param path againt which the the credentials will be tested
|
||||||
|
-- @return out table suitable for inclusion in the script structured output
|
||||||
|
-- (or nil if no credentials succeeded)
|
||||||
|
-- @return txtout table suitable for inclusion in the script textual output
|
||||||
---
|
---
|
||||||
local function register_http_credentials(host, port, login_username, login_password)
|
local function test_credentials (host, port, fingerprint, path)
|
||||||
local c = creds.Credentials:new( SCRIPT_NAME, host, port )
|
local credlst = {}
|
||||||
c:add(login_username, login_password, creds.State.VALID )
|
for _, login_combo in ipairs(fingerprint.login_combos) do
|
||||||
|
local user = login_combo.username
|
||||||
|
local pass = login_combo.password
|
||||||
|
stdnse.debug(2, "Trying login combo -> %s:%s", user, pass)
|
||||||
|
if fingerprint.login_check(host, port, path, user, pass) then
|
||||||
|
stdnse.debug(1, "[%s] valid default credentials found.", fingerprint.name)
|
||||||
|
local cred = stdnse.output_table()
|
||||||
|
cred.username = user
|
||||||
|
cred.password = pass
|
||||||
|
table.insert(credlst, cred)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #credlst == 0 then return nil end
|
||||||
|
-- Some credentials found. Generate the fingerprint output report
|
||||||
|
local out = stdnse.output_table()
|
||||||
|
out.path = path
|
||||||
|
out.credentials = credlst
|
||||||
|
local txtout = {}
|
||||||
|
txtout.name = ("[%s] at %s"):format(fingerprint.name, path)
|
||||||
|
for _, cred in ipairs(credlst) do
|
||||||
|
table.insert(txtout,("%s:%s"):format(stdnse.string_or_blank(cred.username),
|
||||||
|
stdnse.string_or_blank(cred.password)))
|
||||||
|
end
|
||||||
|
-- Register the credentials
|
||||||
|
local credreg = creds.Credentials:new(SCRIPT_NAME, host, port)
|
||||||
|
for _, cred in ipairs(credlst) do
|
||||||
|
credreg:add(cred.username, cred.password, creds.State.VALID )
|
||||||
|
end
|
||||||
|
return out, txtout
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -229,7 +292,8 @@ action = function(host, port)
|
|||||||
local fingerprint_filename = stdnse.get_script_args("http-default-accounts.fingerprintfile") or "http-default-accounts-fingerprints.lua"
|
local fingerprint_filename = stdnse.get_script_args("http-default-accounts.fingerprintfile") or "http-default-accounts-fingerprints.lua"
|
||||||
local category = stdnse.get_script_args("http-default-accounts.category") or false
|
local category = stdnse.get_script_args("http-default-accounts.category") or false
|
||||||
local basepath = stdnse.get_script_args("http-default-accounts.basepath") or "/"
|
local basepath = stdnse.get_script_args("http-default-accounts.basepath") or "/"
|
||||||
local output_lns = {}
|
local output = stdnse.output_table()
|
||||||
|
local text_output = {}
|
||||||
|
|
||||||
-- Determine the target's response to "404" HTTP requests.
|
-- Determine the target's response to "404" HTTP requests.
|
||||||
local status_404, result_404, known_404 = http.identify_404(host,port)
|
local status_404, result_404, known_404 = http.identify_404(host,port)
|
||||||
@@ -278,7 +342,7 @@ action = function(host, port)
|
|||||||
"HTTP request table is empty. This should not happen since we at least made one request.")
|
"HTTP request table is empty. This should not happen since we at least made one request.")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Iterate through responses to find a candidate for login routine
|
-- Iterate through fingerprints to find a candidate for login routine
|
||||||
for _, fingerprint in ipairs(fingerprints) do
|
for _, fingerprint in ipairs(fingerprints) do
|
||||||
local target_check = fingerprint.target_check or default_target_check
|
local target_check = fingerprint.target_check or default_target_check
|
||||||
local credentials_found = false
|
local credentials_found = false
|
||||||
@@ -286,29 +350,17 @@ action = function(host, port)
|
|||||||
for _, probe in ipairs(fingerprint.paths) do
|
for _, probe in ipairs(fingerprint.paths) do
|
||||||
local result = results[pathmap[probe.path]]
|
local result = results[pathmap[probe.path]]
|
||||||
if result and not credentials_found then
|
if result and not credentials_found then
|
||||||
local path = basepath .. probe['path']
|
local path = basepath .. probe.path
|
||||||
|
|
||||||
if target_check(host, port, path, result) then
|
if target_check(host, port, path, result) then
|
||||||
for _, login_combo in ipairs(fingerprint.login_combos) do
|
local out, txtout = test_credentials(host, port, fingerprint, path)
|
||||||
stdnse.debug(2, "Trying login combo -> %s:%s", login_combo["username"], login_combo["password"])
|
if out then
|
||||||
--Check default credentials
|
output[fingerprint.name] = out
|
||||||
if( fingerprint.login_check(host, port, path, login_combo["username"], login_combo["password"]) ) then
|
table.insert(text_output, txtout)
|
||||||
|
credentials_found = true
|
||||||
--Valid credentials found
|
|
||||||
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
|
|
||||||
register_http_credentials(host, port, login_combo["username"], login_combo["password"])
|
|
||||||
credentials_found = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return output, stdnse.format_output(true, text_output)
|
||||||
if #output_lns > 0 then
|
|
||||||
return stdnse.strjoin("\n", output_lns)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user