Nmap Development mailing list archives
Re: [NSE] Local IP geolocation script
From: jah <jah () zadkiel plus com>
Date: Mon, 17 Nov 2008 21:48:05 +0000
On 16/11/2008 19:10, Philipp Emanuel Weidmann wrote:
Hi everyone, It's been quite a while since I worked on Nmap (last time I looked into the code NSE was just a pipe dream), but recently I found time again and whipped up this little script which I find very useful. It provides IP geolocation (country lookup) for each scanned host WITHOUT making any outbound connections and therefore without sending out any data to any registries about your scanning activities. It is in fact a 100% locally acting script. Its lookups are extremely fast (usually less than 0.5 seconds) and since it is absolutely nonintrusive and provides valuable information I have placed it in the "default" category. For its lookups it uses the MaxMind GeoLite Country database from http://www.maxmind.com (they are claiming 99.5% accuracy; I personally have not found one IP it is incorrect about. It is also updated regularly). To make this script work, install it as usual in your /scripts directory, then download the GeoLite database from http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip and unpack it into your main Nmap directory (where the other data files are so it can be found by nmap.fetchfile). I hacked this together without knowing any LUA, so if you can improve it in any way, please do so. Sample output: Interesting ports on fx-in-f99.google.com (74.125.39.99): PORT STATE SERVICE 5/tcp filtered unknown Host script results: |_ IP geolocation: United States (US) Hope you find it as useful as I do. Have a great day. Philipp Emanuel Weidmann
Hi Philipp This is a nice script and probably caters well for the seriously paranoid! I think it should also be in the "safe" category, but not so sure about being in the default one given that it requires a file which is unlikely (?) to be shipped with Nmap and thus not present in many installations. Having said that, it occurred to me that nmap.fetchfile() could be called from the scripts hostrule to check whether the file is present and to store a value in the registry so that this check would not need to be repeated for any further targets in that hostgroup. This would have the effect of reducing some of the time wasted on calling the script if the required file is not present. The speed of lookup is OK for a single target, but for a large number of targets these small timescales would add-up to be quite lengthy. This is because the geo file would be read for each target consecutively as, with no network activity, each instance of the script would complete before the next one begins. Parsing the geo file once and storing the data for access by other instances of the script would slow down the execution for a single target by a small amount, but subsequent instances of the script would finish much more quickly and this would have a big impact when scanning lots of targets. Some other little points: ipOps.todword() could be used to convert host.ip into a number. The script should be prevented from running against IPv6 targets where it would fail. The script "id" field is being deprecated and the script filename is instead printed in the script results - so a more descriptive filename such as ip-geolocation.nse might be better. You might also like to have a look at http://nmap.org/book/nsedoc.html for guidance on documenting the script. I've attached ip-geolocation.nse which calls datafiles.parse_file() inside the hostrule - combining the check for existence of the file and the one-time parsing and storage in the registry. The hostrule also checks for IPv6 addresses (host.ip contains a colon). Regards, jah
-- NOTE: In order for this script to work, you must download the GeoLite Country database from -- http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip, -- unpack it, and place it in the Nmap main directory (where the other Nmap data files are, too) description = "Displays the location of the scanned host (country only), \ taken from the GeoLite Country database.\n\ NO information WHATSOEVER is sent from the scanning machine." author = "Philipp E. Weidmann <philipp.weidmann () gmx de>" license = "Script: Same as Nmap, see http://nmap.org/book/man-legal.html; \ GeoLite Country database: See http://www.maxmind.com/download/geoip/database/LICENSE.txt" categories = {"default", "discovery", "safe"} local ipOps = require "ipOps" local stdnse = require "stdnse" local datafiles = require "datafiles" local geofile = "GeoIPCountryWhois.csv" if not nmap.registry.locateip then nmap.registry.locateip = {} end hostrule = function(host) if host.ip:match(":") or ipOps.isPrivate(host.ip) then return false end local status, lookup if nmap.registry.locateip.lookup == nil then local p = { -- table passed to parse_file range = {function(l) a,b = l:match('"(%d+)","(%d+)"') return {lo=tonumber(a),hi=tonumber(b)} end}, co = {function(l) a,b = l:match('"(%u%u)","(.+)"') return ("%s (%s)"):format(b or "",a or "") end} } status, lookup = datafiles.parse_file(geofile,p) if not status then stdnse.print_debug(1, "Error finding or trying to parse %s", geofile) nmap.registry.locateip.lookup = false -- prevent repetition of parse_file return false end nmap.registry.locateip.lookup = lookup elseif nmap.registry.locateip.lookup == false then return false end return true -- host.ip is ok and data is in the registry end action = function(host) local lookup = nmap.registry.locateip.lookup local ipnumber = ipOps.todword(host.ip) for i=1,#lookup.co,1 do if ipnumber >= lookup.range[i].lo and ipnumber <= lookup.range[i].hi then return lookup.co[i] end end end
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [NSE] Local IP geolocation script Philipp Emanuel Weidmann (Nov 16)
- Re: [NSE] Local IP geolocation script jah (Nov 17)
- Re: [NSE] Local IP geolocation script Kris Katterjohn (Nov 17)
- Re: [NSE] scripts/data directory jah (Nov 17)
- Re: [NSE] scripts/data directory Kris Katterjohn (Nov 17)
- Re: [NSE] scripts/data directory jah (Nov 18)
- Re: [NSE] Local IP geolocation script Kris Katterjohn (Nov 17)
- Re: [NSE] Local IP geolocation script jah (Nov 17)
- Re: [NSE] Local IP geolocation script Philipp Emanuel Weidmann (Nov 18)
- Re: [NSE] Local IP geolocation script Ron (Nov 18)
- Re: [NSE] Local IP geolocation script Fyodor (Nov 18)
- Re: [NSE] Local IP geolocation script Philipp Emanuel Weidmann (Nov 18)
- Re: [NSE] Local IP geolocation script Fyodor (Nov 18)
- Re: [NSE] Local IP geolocation script Ron (Nov 18)
