diff --git a/CHANGELOG b/CHANGELOG index 8f88f5a36..a0f9a719b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added the hostmap script by Ange Gutek. This uses a third-party + database to look up other hostnames mapping to the target. + o [NSE] Added the ability to send and receive on unconnected sockets. This can be used, for example, to receive UDP broadcasts without using pcap. A number of scripts have been changed so that they can diff --git a/scripts/hostmap.nse b/scripts/hostmap.nse new file mode 100644 index 000000000..7153aacb0 --- /dev/null +++ b/scripts/hostmap.nse @@ -0,0 +1,123 @@ +description = [[ +Tries to find hostnames that resolve to the target's IP address. + +The script works by querying the online database at +http://www.bfk.de/bfk_dnslogger.html. It is in the "external" category +because of this. Be aware that this script could expose the targets of a +scan to a third party. +]] + +--- +-- @args hostmap.prefix If set, saves the output for each host in a file +-- called "". The file contains one entry per line. +-- @args newtargets If set, add the new hostnames to the scanning queue. +-- This the names presumably resolve to the same IP address as the +-- original target, this is only useful for services such as HTTP that +-- can change their behavior based on hostname. +-- +-- @usage +-- nmap --script hostmap --script-args hostmap.prefix=hostmap- +-- +-- @output +-- Host script results: +-- | hostmap: Saved to hostmap-nmap.org +-- | insecure.org +-- | 74.207.254.18 +-- | web.insecure.org +-- | download.insecure.org +-- | images.insecure.org +-- | www.insecure.org +-- | nmap.org +-- | www.nmap.org +-- | sectools.org +-- | mirror.sectools.org +-- | www.sectools.org +-- |_seclists.org + +author = "Ange Gutek " + +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" + +categories = {"external", "discovery", "intrusive"} + +require "dns" +require "ipOps" +require "http" +require "stdnse" +require "target" + +local HOSTMAP_SERVER = "www.bfk.de" + +local filename_escape, write_file + +hostrule = function(host) + return not ipOps.isPrivate(host.ip) +end + +action = function(host) + local query = "/bfk_dnslogger.html?query=" .. host.ip + local response + + response = http.get(HOSTMAP_SERVER, 80, query) + if not response.status then + return string.format("Error: ould not GET http://%s%s", HOSTMAP_SERVER, query) + end + + local hostnames = {} + for entry in string.gmatch(response.body, "#result\">([^<]-)") do + if not hostnames[entry] then + if target.ALLOW_NEW_TARGETS then + local status, err = target.add(entry) + end + hostnames[entry] = true + if string.match(entry, "%d+%.%d+%.%d+%.%d+") or dns.query(entry) then + hostnames[#hostnames + 1] = entry + else + hostnames[#hostnames + 1] = entry .. " (cannot resolve)" + end + end + end + + if #hostnames == 0 then + if not string.find(response.body, "

The server returned no hits.

") then + return "Error: found no hostnames but not the marker for \"no hostnames found\" (pattern error?)" + end + return + end + + local hostnames_str = stdnse.strjoin("\n", hostnames) + local output_str + + local filename_prefix = stdnse.get_script_args("hostmap.prefix") + 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 diff --git a/scripts/script.db b/scripts/script.db index 0940866d8..56b8fb765 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -38,6 +38,7 @@ Entry { filename = "ftp-bounce.nse", categories = { "default", "intrusive", } } Entry { filename = "ftp-brute.nse", categories = { "auth", "intrusive", } } Entry { filename = "ftp-libopie.nse", categories = { "intrusive", "vuln", } } Entry { filename = "giop-info.nse", categories = { "discovery", "safe", } } +Entry { filename = "hostmap.nse", categories = { "discovery", "external", "intrusive", } } Entry { filename = "html-title.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "http-auth.nse", categories = { "auth", "default", "intrusive", } } Entry { filename = "http-brute.nse", categories = { "auth", "intrusive", } }