1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-27 01:49:03 +00:00

New tableaux library containing table auxiliary functions.

This commit is contained in:
dmiller
2018-10-17 15:34:30 +00:00
parent c76424deb7
commit dcc0e3ed7e
43 changed files with 203 additions and 238 deletions

View File

@@ -2,6 +2,7 @@ local ajp = require "ajp"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
Discovers which options are supported by the AJP (Apache JServ
@@ -44,7 +45,7 @@ local UNINTERESTING_METHODS = { "GET", "HEAD", "POST", "OPTIONS" }
local function filter_out(t, filter)
local result = {}
for _, e in ipairs(t) do
if ( not(stdnse.contains(filter, e)) ) then
if ( not(tableaux.contains(filter, e)) ) then
result[#result + 1] = e
end
end

View File

@@ -6,6 +6,7 @@ local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
description = [[
Obtains information from a Bitcoin server by calling <code>getinfo</code> on its JSON-RPC interface.
@@ -124,7 +125,7 @@ end
local function formatpairs(info)
local result = stdnse.output_table()
local keys = stdnse.keys(info)
local keys = tableaux.keys(info)
table.sort(keys)
for _, k in ipairs(keys) do
if info[k] ~= "" then

View File

@@ -4,6 +4,7 @@ local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "tableaux"
description = [[
Enumerates DNS names using the DNSSEC NSEC-walking technique.
@@ -119,16 +120,6 @@ local function guess_domain(host)
end
end
local function invert(t)
local result = {}
for k, v in pairs(t) do
result[v] = k
end
return result
end
-- RFC 952: "A 'name' is a text string up to 24 characters drawn from the
-- alphabet (A-Z), digits (0-9), minus sign (-), and period (.). ... The first
-- character must be an alpha character."
@@ -138,7 +129,7 @@ end
-- RFC 2782: An underscore (_) is prepended to the service identifier to avoid
-- collisions with DNS labels that occur in nature.
local DNS_CHARS = { string.byte("-0123456789_abcdefghijklmnopqrstuvwxyz", 1, -1) }
local DNS_CHARS_INV = invert(DNS_CHARS)
local DNS_CHARS_INV = tableaux.invert(DNS_CHARS)
-- Return the lexicographically next component, or nil if component is the
-- lexicographically last.

View File

@@ -5,6 +5,7 @@ local base32 = require "base32"
local nmap = require "nmap"
local string = require "string"
local table = require "table"
local tableaux = require "table"
local rand = require "rand"
local openssl = stdnse.silent_require "openssl"
@@ -217,7 +218,7 @@ local function query_for_hashes(host,subdomain,domain)
for _, nsec3 in ipairs(auth_filter(result, "NSEC3")) do
local h1 = string.lower(remove_suffix(nsec3.dname,domain))
local h2 = string.lower(nsec3.hash.base32)
if not stdnse.contains(all_results,"nexthash " .. h1 .. " " .. h2) then
if not tableaux.contains(all_results,"nexthash " .. h1 .. " " .. h2) then
table.insert(all_results, "nexthash " .. h1 .. " " .. h2)
stdnse.debug1("nexthash " .. h1 .. " " .. h2)
end

View File

@@ -3,6 +3,7 @@ local nmap = require "nmap"
local ssh1 = require "ssh1"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
Attempts to discover multihomed systems by analysing and comparing
@@ -68,7 +69,7 @@ local function processSSLCerts(tab)
for host, v in pairs(tab) do
for port, sha1 in pairs(v) do
ssl_certs[sha1] = ssl_certs[sha1] or {}
if ( not stdnse.contains(ssl_certs[sha1], host.ip) ) then
if ( not tableaux.contains(ssl_certs[sha1], host.ip) ) then
table.insert(ssl_certs[sha1], host.ip)
end
end
@@ -97,7 +98,7 @@ local function processSSHKeys(tab)
hostkeys[fp] = {}
end
-- discard duplicate IPs
if not stdnse.contains(hostkeys[fp], ip) then
if not tableaux.contains(hostkeys[fp], ip) then
table.insert(hostkeys[fp], ip)
end
end
@@ -121,12 +122,12 @@ local function processNBStat(tab)
local results, mac_table, name_table = {}, {}, {}
for host, v in pairs(tab) do
mac_table[v.mac] = mac_table[v.mac] or {}
if ( not(stdnse.contains(mac_table[v.mac], host.ip)) ) then
if ( not(tableaux.contains(mac_table[v.mac], host.ip)) ) then
table.insert(mac_table[v.mac], host.ip)
end
name_table[v.server_name] = name_table[v.server_name] or {}
if ( not(stdnse.contains(name_table[v.server_name], host.ip)) ) then
if ( not(tableaux.contains(name_table[v.server_name], host.ip)) ) then
table.insert(name_table[v.server_name], host.ip)
end
end
@@ -157,7 +158,7 @@ local function processMAC(tab)
if ( host.mac_addr ) then
mac = stdnse.format_mac(host.mac_addr)
mac_table[mac] = mac_table[mac] or {}
if ( not(stdnse.contains(mac_table[mac], host.ip)) ) then
if ( not(tableaux.contains(mac_table[mac], host.ip)) ) then
table.insert(mac_table[mac], host.ip)
end
end

View File

@@ -4,6 +4,7 @@ local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
description = [[
Performs a Forward-confirmed Reverse DNS lookup and reports anomalous results.
@@ -127,7 +128,7 @@ action = function(host)
str_out = nil
elseif str_out == nil then
-- we failed, and need to format a short output string
fail_addrs = stdnse.keys(fail_addrs)
fail_addrs = tableaux.keys(fail_addrs)
if #fail_addrs > 0 then
table.sort(fail_addrs)
str_out = string.format("FAIL (%s)", table.concat(fail_addrs, ", "))

View File

@@ -3,6 +3,7 @@ local nmap = require "nmap"
local lpeg = require "lpeg"
local U = require "lpeg-utility"
local table = require "table"
local tableaux = require "table"
description = [[
Prints the readable strings from service fingerprints of unknown services.
@@ -87,7 +88,7 @@ action = function(host, port)
-- Get the table of probe responses
local responses = U.parse_fp(port.version.service_fp)
-- extract the probe names
local probes = stdnse.keys(responses)
local probes = tableaux.keys(responses)
-- If there were no probes (WEIRD!) we're done.
if #probes <= 0 then
return nil

View File

@@ -50,6 +50,7 @@ local stdnse = require "stdnse"
local string = require "string"
local target = require "target"
local table = require "table"
local tableaux = require "table"
-- Different from stdnse.get_hostname
-- this function returns nil if the host is only known by IP address
@@ -69,7 +70,7 @@ local function query_ctlogs(host)
return string.format("Error: could not GET http://%s%s", "crt.sh", query)
end
for domain in string.gmatch(response.body, "name_value\":\"(.-)\"") do
if not stdnse.contains(hostnames, domain) and domain ~= "" then
if not tableaux.contains(hostnames, domain) and domain ~= "" then
if target.ALLOW_NEW_TARGETS then
local status, err = target.add(domain)
end

View File

@@ -4,6 +4,7 @@ local re = require "re"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
Grabs affiliate network IDs (e.g. Google AdSense or Analytics, Amazon
@@ -133,7 +134,7 @@ local function postaction()
siteids[id] = {}
end
-- discard duplicate IPs
if not stdnse.contains(siteids[id], site) then
if not tableaux.contains(siteids[id], site) then
table.insert(siteids[id], site)
end
end

View File

@@ -4,6 +4,7 @@ local vulns = require "vulns"
local nmap = require "nmap"
local shortport = require "shortport"
local table = require "table"
local tableaux = require "table"
local string = require "string"
local slaxml = require "slaxml"
@@ -156,7 +157,7 @@ local tlds_instantdomainsearch = {".com", ".net", ".org", ".co", ".info", ".biz"
---
local function check_domain (domain)
local name, tld = domain:match("(%w*)%.*(%w*%.%w+)$")
if not(stdnse.contains(tlds_instantdomainsearch, tld)) then
if not(tableaux.contains(tlds_instantdomainsearch, tld)) then
stdnse.debug(1, "TLD '%s' is not supported by instantdomainsearch.com. Check manually.", tld)
return nil
end
@@ -227,11 +228,11 @@ function check_crossdomain(host, port, lookup)
if domain ~= nil then
--Deals with tlds with double extension
local tld = domain:match("%w*(%.%w*)%.%w+$")
if tld ~= nil and not(stdnse.contains(tlds_instantdomainsearch, tld)) then
if tld ~= nil and not(tableaux.contains(tlds_instantdomainsearch, tld)) then
domain = domain:match("%w*%.(.*)$")
end
--We add domains only once as they can appear multiple times
if not(stdnse.contains(trusted_domains, domain)) then
if not(tableaux.contains(trusted_domains, domain)) then
stdnse.debug(1, "Added trusted domain:%s", domain)
table.insert(trusted_domains, domain)
--Lookup domains if script argument is set
@@ -280,7 +281,7 @@ Forgery attacks, and may allow third parties to access sensitive data meant for
local check, domains, domains_available, content = check_crossdomain(host, port, lookup)
local mt = {__tostring=function(p) return ("%s:\n %s"):format(p.name, p.body:gsub("\n", "\n ")) end}
if check then
if stdnse.contains(domains, "*") or stdnse.contains(domains, "https://") or stdnse.contains(domains, "http://") then
if tableaux.contains(domains, "*") or tableaux.contains(domains, "https://") or tableaux.contains(domains, "http://") then
vuln.state = vulns.STATE.VULN
else
vuln.state = vulns.STATE.LIKELY_VULN

View File

@@ -6,6 +6,7 @@ local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "tableaux"
local url = require "url"
local rand = require "rand"
@@ -310,20 +311,6 @@ local detect_form = function (host, port, path, hostname)
return nil, string.format("Unable to detect a login form at path %q", path)
end
-- Recursively copy a table.
-- Only recurs when a value is a table, other values are copied by assignment.
local function tcopy (t)
local tc = {};
for k,v in pairs(t) do
if type(v) == "table" then
tc[k] = tcopy(v);
else
tc[k] = v;
end
end
return tc;
end
-- TODO: expire cookies
local function update_cookies (old, new)
for i, c in ipairs(new) do
@@ -398,9 +385,9 @@ Driver = {
if not thread then
thread = {
-- copy of form fields so we don't clobber another thread's passvar
params = tcopy(self.options.formfields),
params = tableaux.tcopy(self.options.formfields),
-- copy of options so we don't clobber another thread's cookies
opts = tcopy(self.options.http_options),
opts = tableaux.tcopy(self.options.http_options),
}
self.options.threads[tid] = thread
end

View File

@@ -3,6 +3,7 @@ local httpspider = require "httpspider"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
@@ -304,7 +305,7 @@ action = function(host, port)
count = count + pattern_count
for match in body:gmatch(pattern) do
local validate = BUILT_IN_PATTERNS[pattern_name]and BUILT_IN_PATTERNS[pattern_name]['validate'] or default
if validate(match) and not stdnse.contains(all_match, match) then
if validate(match) and not tableaux.contains(all_match, match) then
table.insert(pattern_type, "+ " .. shortenMatch(match))
table.insert(all_match, match)
else

View File

@@ -4,6 +4,7 @@ local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
local rand = require "rand"
description = [[
@@ -80,7 +81,7 @@ local function filter_out(t, filter)
local result = {}
local _, e, f
for _, e in ipairs(t) do
if not stdnse.contains(filter, e) then
if not tableaux.contains(filter, e) then
result[#result + 1] = e
end
end
@@ -159,14 +160,14 @@ action = function(host, port)
local status_lines = {}
for _, method in pairs(SAFE_METHODS) do
if not stdnse.contains(methods, method) then
if not tableaux.contains(methods, method) then
table.insert(to_test, method)
end
end
if test_all_unsafe then
for _, method in pairs(UNSAFE_METHODS) do
if not stdnse.contains(methods, method) then
if not tableaux.contains(methods, method) then
table.insert(to_test, method)
end
end
@@ -212,7 +213,7 @@ action = function(host, port)
if method == "OPTIONS" then
-- Use the saved value.
str = options_status_line
elseif stdnse.contains(to_test, method) then
elseif tableaux.contains(to_test, method) then
-- use the value saved earlier.
str = status_lines[method]
-- this case arises when methods in the Public or Allow headers are retested.

View File

@@ -75,6 +75,7 @@ local url = require 'url'
local httpspider = require 'httpspider'
local string = require 'string'
local table = require 'table'
local tableaux = require 'tableaux'
-- this is a variable that will hold the function that checks if a pattern we are searching for is in
-- response's body
@@ -176,17 +177,6 @@ local function check_responses(urls, responses)
return suspects
end
-- return a shallow copy of t
local function tcopy(t)
local k = next(t)
local out = {}
while k do
out[k] = t[k]
k = next(t, k)
end
return out
end
portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open")
function action(host, port)
@@ -268,7 +258,7 @@ function action(host, port)
local rfi = { name = "Possible RFI in form fields" }
for path, forms in pairs(output.Forms) do
for fid, fobj in pairs(forms) do
local out = tcopy(fobj["Vulnerable fields"])
local out = tableaux.shallow_tcopy(fobj["Vulnerable fields"])
out.name = string.format('Form "%s" at %s (action %s) with fields:',
fid, path, fobj["Action"])
table.insert(rfi, out)
@@ -279,7 +269,7 @@ function action(host, port)
if #output.Queries > 0 then
local rfi = { name = "Possible RFI in query parameters" }
for path, queries in pairs(output.Queries) do
local out = tcopy(queries)
local out = tableaux.shallow_tcopy(queries)
out.name = string.format('Path %s with queries:', path)
table.insert(rfi, out)
end

View File

@@ -1,6 +1,7 @@
local http = require "http"
local ipOps = require "ipOps"
local table = require "table"
local tableaux = require "table"
local shortport = require "shortport"
local stdnse = require "stdnse"
@@ -108,7 +109,7 @@ local function getIPs(body)
end
end
end
return stdnse.keys(result)
return tableaux.keys(result)
end
-- a function to test the PROPFIND method.

View File

@@ -2,6 +2,7 @@ local mssql = require "mssql"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
-- -*- mode: lua -*-
-- vim: set filetype=lua :
@@ -177,7 +178,7 @@ local function process_instance( instance )
end
for k, v in pairs(dbs.rows) do
if ( not( stdnse.contains( done_dbs, v[1] ) ) ) then
if ( not( tableaux.contains( done_dbs, v[1] ) ) ) then
local query = [[ SELECT so.name 'table', sc.name 'column', st.name 'type', sc.length
FROM %s..syscolumns sc, %s..sysobjects so, %s..systypes st
WHERE so.id = sc.id AND sc.xtype=st.xtype AND

View File

@@ -2,6 +2,7 @@ local nbd = require "nbd"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
Displays protocol and block device information from NBD servers.
@@ -160,7 +161,7 @@ action = function(host, port)
-- Format exported block device information.
local exports = stdnse.output_table()
local no_shares = true
local names = stdnse.keys(comm.exports)
local names = tableaux.keys(comm.exports)
-- keep exports in stable order
table.sort(names)
for _, name in ipairs(names) do

View File

@@ -2,6 +2,7 @@ local ipOps = require "ipOps"
local nmap = require "nmap"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "table"
description = [[
Creates a reverse index at the end of scan output showing which hosts run a
@@ -101,7 +102,7 @@ postaction = function()
local results = stdnse.output_table()
for proto, ports in pairs(db) do
local portnumbers = stdnse.keys(ports)
local portnumbers = tableaux.keys(ports)
table.sort(portnumbers)
for _, port in ipairs(portnumbers) do
local result_entries = ports[port]

View File

@@ -3,6 +3,7 @@ local smb = require "smb"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
description = [[
Obtains a list of groups from the remote Windows system, as well as a list of the group's users.
@@ -148,14 +149,14 @@ action = function(host)
local response = stdnse.output_table()
local response_str = {}
local domains = stdnse.keys(groups)
local domains = tableaux.keys(groups)
table.sort(domains)
for _, domain_name in ipairs(domains) do
local dom_groups = stdnse.output_table()
response[domain_name] = dom_groups
local domain_data = groups[domain_name]
local rids = stdnse.keys(domain_data)
local rids = tableaux.keys(domain_data)
table.sort(rids)
for _, rid in ipairs(rids) do
local group_data = domain_data[rid]

View File

@@ -6,6 +6,7 @@ local ssh2 = require "ssh2"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "table"
local base64 = require "base64"
local comm = require "comm"
@@ -189,7 +190,7 @@ local function check_keys(host, keys, f)
end
end
else
if stdnse.contains(possible_host_names, parts[1]) then
if tableaux.contains(possible_host_names, parts[1]) then
stdnse.debug2("Found an entry that matches: %s", parts[1])
table.insert(keys_from_file, ("%s %s"):format(parts[2], parts[3]))
else
@@ -367,7 +368,7 @@ local function postaction()
}
end
-- discard duplicate IPs
if not stdnse.contains(hostkeys[fp], ip) then
if not tableaux.contains(hostkeys[fp], ip) then
table.insert(hostkeys[fp], ip)
end
end

View File

@@ -4,6 +4,7 @@ local sslcert = require('sslcert')
local stdnse = require('stdnse')
local vulns = require('vulns')
local tls = require 'tls'
local tableaux = require "table"
description = [[
Detects whether a server is vulnerable to the SSL/TLS "CCS Injection"
@@ -143,7 +144,7 @@ local function test_ccs_injection(host, port, version)
["record_protocol"] = (version == "SSLv3") and "SSLv3" or "TLSv1.0",
-- Claim to support every cipher
-- Doesn't work with IIS, but IIS isn't vulnerable
["ciphers"] = stdnse.keys(tls.CIPHERS),
["ciphers"] = tableaux.keys(tls.CIPHERS),
["compressors"] = {"NULL"},
["extensions"] = {
-- Claim to support common elliptic curves

View File

@@ -4,6 +4,7 @@ local shortport = require('shortport')
local sslcert = require('sslcert')
local stdnse = require('stdnse')
local string = require "string"
local tableaux = require "table"
local vulns = require('vulns')
local have_tls, tls = pcall(require,'tls')
assert(have_tls, "This script requires the tls.lua library from https://nmap.org/nsedoc/lib/tls.html")
@@ -73,7 +74,7 @@ local function testversion(host, port, version)
["protocol"] = version,
-- Claim to support every cipher
-- Doesn't work with IIS, but IIS isn't vulnerable
["ciphers"] = stdnse.keys(tls.CIPHERS),
["ciphers"] = tableaux.keys(tls.CIPHERS),
["compressors"] = {"NULL"},
["extensions"] = {
-- Claim to support common elliptic curves

View File

@@ -4,6 +4,7 @@ local sslcert = require "sslcert"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "tableaux"
local tls = require "tls"
local listop = require "listop"
local vulns = require "vulns"
@@ -61,16 +62,6 @@ dependencies = {"ssl-enum-ciphers", "https-redirect"}
-- http://seclists.org/nmap-dev/2010/q1/859
local CHUNK_SIZE = 64
local function keys(t)
local ret = {}
local k, v = next(t)
while k do
ret[#ret+1] = k
k, v = next(t, k)
end
return ret
end
-- Add additional context (protocol) to debug output
local function ctx_log(level, protocol, fmt, ...)
return stdnse.print_debug(level, "(%s) " .. fmt, protocol, ...)
@@ -184,20 +175,6 @@ local function base_extensions(host)
}
end
-- Recursively copy a table.
-- Only recurs when a value is a table, other values are copied by assignment.
local function tcopy (t)
local tc = {};
for k,v in pairs(t) do
if type(v) == "table" then
tc[k] = tcopy(v);
else
tc[k] = v;
end
end
return tc;
end
-- Find which ciphers out of group are supported by the server.
local function find_ciphers_group(host, port, protocol, group)
local name, protocol_worked, record, results
@@ -305,7 +282,7 @@ local function check_fallback_scsv(host, port, protocol, ciphers)
["extensions"] = base_extensions(host),
}
t["ciphers"] = tcopy(ciphers)
t["ciphers"] = tableaux.tcopy(ciphers)
t.ciphers[#t.ciphers+1] = "TLS_FALLBACK_SCSV"
-- TODO: remove this check after the next release.

View File

@@ -1,6 +1,7 @@
local nmap = require "nmap"
local shortport = require "shortport"
local table = require "table"
local tableaux = require "table"
local stdnse = require "stdnse"
local string = require "string"
local sslcert = require "sslcert"
@@ -132,7 +133,7 @@ local function do_setup(host, port)
end
end
socket:set_timeout(timeout)
socket:send(sslv2.client_hello(stdnse.keys(sslv2.SSL_CIPHER_CODES)))
socket:send(sslv2.client_hello(tableaux.keys(sslv2.SSL_CIPHER_CODES)))
local status, buffer = sslv2.record_buffer(socket)
if not status then
socket:close()

View File

@@ -4,6 +4,7 @@ local nmap = require "nmap"
local stdnse = require "stdnse"
local tab = require "tab"
local table = require "table"
local tableaux = require "table"
local target = require "target"
local multicast = require "multicast"
@@ -103,7 +104,7 @@ end
local function format_output(results)
local output = tab.new()
local xmlout = {}
local ips = stdnse.keys(results)
local ips = tableaux.keys(results)
table.sort(ips)
for i, ip in ipairs(ips) do

View File

@@ -4,6 +4,7 @@ local shortport = require("shortport")
local sslcert = require("sslcert")
local stdnse = require("stdnse")
local table = require("table")
local tableaux = require "table"
local tls = require "tls"
local vulns = require("vulns")
local rand = require "rand"
@@ -213,7 +214,7 @@ local function is_vuln(host, port, version)
["session_id"] = sid_old,
-- Claim to support every cipher
-- Doesn't work with IIS, but only F5 products should be affected
["ciphers"] = stdnse.keys(tls.CIPHERS),
["ciphers"] = tableaux.keys(tls.CIPHERS),
["compressors"] = {"NULL"},
["extensions"] = {
-- Claim to support common elliptic curves

View File

@@ -6,6 +6,7 @@ local stdnse = require "stdnse"
local strbuf = require "strbuf"
local string = require "string"
local table = require "table"
local tableaux = require "table"
description = [[
Performs XMLRPC Introspection via the system.listMethods method.
@@ -86,7 +87,7 @@ action = function(host, port)
}
parser:parseSAX(response.body, {stripWhitespace=true})
if nmap.verbosity() > 1 and stdnse.contains(output["Supported Methods"], "system.methodHelp") then
if nmap.verbosity() > 1 and tableaux.contains(output["Supported Methods"], "system.methodHelp") then
for i, method in ipairs(output["Supported Methods"]) do
data = '<methodCall> <methodName>system.methodHelp</methodName> <params> <param><value> <string>' .. method .. '</string> </value></param> </params> </methodCall>'
response = http.post(host, port, url, {header = {["Content-Type"] = "application/x-www-form-urlencoded"}}, nil, data)