diff --git a/scripts/ip-geolocation-geobytes.nse b/scripts/ip-geolocation-geobytes.nse new file mode 100755 index 000000000..e7cc295e9 --- /dev/null +++ b/scripts/ip-geolocation-geobytes.nse @@ -0,0 +1,74 @@ +description = [[ +This script looks up the host's IP address using the Geobytes geolocation web +service. The limit of lookups using this service is 20 requests per hour. Once +the limit is reached, an nmap.registry["ip-geolocation-geobytes"].blocked +boolean is set so no further requests are made during a scan. +]] + +--- +-- @usage +-- nmap --script ip-geolocation-geobytes +-- +-- @output +-- | ip-geolocation-geobytes: +-- | 74.207.244.221 (scanme.nmap.org) +-- | coordinates (lat,lon): 43.667,-79.417 +-- |_ city: Toronto, Ontario, Canada +-- + +author = "Gorjan Petrovski" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"discovery","external","safe"} + +require "nmap" +require "stdnse" +require "ipOps" +require "json" +require "http" + +hostrule = function(host) + local is_private, err = ipOps.isPrivate( host.ip ) + if is_private == nil then + stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err ) + return false + end + return not is_private +end + +-- Limit is 20 request per hour per requesting host, when reached all table +-- values are filled with a "Limit Exceeded" value. A record in the registry is +-- made so no more requests are made to the server during one scan +local geobytes = function(ip) + if nmap.registry["ip-geolocation-geobytes"] and nmap.registry["ip-geolocation-geobytes"].blocked then + return nil + end + local response = http.get("www.geobytes.com", 80, "/IpLocator.htm?GetLocation&template=json.txt&IpAddress="..ip, nil) + local stat, out = json.parse(response.body) + local loc = out.geobytes + local output={} + if stat then + if loc.city and loc.city == "Limit Exceeded" then + if not nmap.registry["ip-geolocation-geobytes"] then nmap.registry["ip-geolocation-geobytes"]={} end + nmap.registry["ip-geolocation-geobytes"].blocked = true + return nil + end + -- Process output + table.insert(output, "coordinates (lat,lon): " .. loc.latitude .. "," .. loc.longitude) + table.insert(output,"city: ".. loc.city..", ".. loc.region..", ".. loc.country) + return output + end + return nil +end + +action = function(host,port) + local output = geobytes(host.ip) + + if(#output~=0) then + output.name = host.ip + if host.targetname then + output.name = output.name.." ("..host.targetname..")" + end + end + + return stdnse.format_output(true,output) +end