hostmap.provider
.
The supported provider identifiers are:
* BFK
* BING
The script is in the "external" category because it sends target IPs to a third party in order to query their database.
]]
---
-- @args hostmap.prefix If set, saves the output for each host in a file
-- called "The server returned no hits.
") then return "Error: found no hostnames but not the marker for \"no hostnames found\" (pattern error?)" end end return hostnames end local function query_bing(ip) local query = "/print.php?ip=" .. ip local response local entries response = http.get(HOSTMAP_BING_SERVER, 80, query) local hostnames = {} if not response.status then return string.format("Error: could not GET http://%s%s", HOSTMAP_BING_SERVER, query) end entries = stdnse.strsplit(",", response.body); for _, entry in pairs(entries) do if not hostnames[entry] and entry ~= "" then if target.ALLOW_NEW_TARGETS then local status, err = target.add(entry) end hostnames[#hostnames + 1] = entry end end if #hostnames == 0 then if not string.find(response.body, "no results") then return "Error: found no hostnames but not the marker for \"no hostnames found\" (pattern error?)" end end return hostnames end action = function(host) local filename_prefix = stdnse.get_script_args("hostmap.prefix") local provider = stdnse.get_script_args("hostmap.provider") or HOSTMAP_DEFAULT_PROVIDER local hostnames = {} local hostnames_str, output_str --select provider accordingly if provider == "BFK" then stdnse.print_debug(1, "Using database: %s", HOSTMAP_BFK_SERVER) hostnames = query_bfk(host.ip) elseif provider == "BING" then stdnse.print_debug(1, "Using database: %s", HOSTMAP_BING_SERVER) hostnames = query_bing(host.ip) else stdnse.print_debug(1, "Using all databases") local bing_hostnames = query_bing(host.ip) local bfk_hostnames = query_bfk(host.ip) local found --merge into same table local bing_hosts_type = type(bing_hostnames) local bfk_hosts_type = type(bfk_hostnames) --if one service does not respond, fail gracefully if bing_hosts_type == "table" and bfk_hosts_type == "table" then for k,bfk_host in pairs(bfk_hostnames) do found = false for _,bing_host in pairs(bing_hostnames) do if bfk_host == bing_host then found = true end end if found == false and bfk_host ~= true then table.insert(bing_hostnames, bfk_host) end end hostnames = bing_hostnames elseif bing_hosts_type == "table" and bfk_hosts_type ~= "table" then stdnse.print_debug(1, "BFK did not return results.") hostnames = bing_hostnames elseif bing_hosts_type ~= "table" and bfk_hosts_type == "table" then stdnse.print_debug(1, "BING did not return results.") hostnames = bfk_hostnames end end if type(hostnames) == "string" then return hostnames end hostnames_str = stdnse.strjoin("\n", hostnames) --write to file if filename_prefix then local filename = filename_prefix .. filename_escape(host.targetname or host.ip) local status, err = write_file(filename, hostnames_str .. "\n") if status then output_str = string.format("Saved to %s\n", filename) else output_str = string.format("Error saving to %s: %s\n", filename, err) end else output_str = "\n" end output_str = output_str .. stdnse.strjoin("\n", hostnames) return output_str end -- Escape some potentially unsafe characters in a string meant to be a filename. function filename_escape(s) return string.gsub(s, "[%z/=]", function(c) return string.format("=%02X", string.byte(c)) end) end function write_file(filename, contents) local f, err = io.open(filename, "w") if not f then return f, err end f:write(contents) f:close() return true end