1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
local geoip = require "geoip"
local io = require "io"
local oops = require "oops"
local stdnse = require "stdnse"
local table = require "table"
description = [[
This script queries the Nmap registry for the GPS coordinates of targets stored
by previous geolocation scripts and produces a KML file of points representing
the targets.
]]
---
-- @usage
-- nmap -sn -Pn --script ip-geolocation-geoplugin,ip-geolocation-map-kml --script-args ip-geolocation-map-kml.map_path=map.kml <target>
--
-- @output
-- | ip-geolocation-map-kml:
-- |_ The map has been saved at 'map.kml'.
--
-- @args ip-geolocation-map-kml.map_path (REQUIRED)
--
-- @see ip-geolocation-geoplugin.nse
-- @see ip-geolocation-ipinfodb.nse
-- @see ip-geolocation-map-bing.nse
-- @see ip-geolocation-map-google.nse
-- @see ip-geolocation-maxmind.nse
author = "Mak Kolybabi <mak@kolybabi.com>"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"safe"}
local render = function(path)
local kml = {'<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n <Document>'}
for ip, coords in pairs(geoip.get_all_by_ip()) do
table.insert(kml, ([[
<Placemark>
<name>%s</name>
<Point>
<coordinates>%s,%s</coordinates>
</Point>
</Placemark>]]):format(ip, coords["longitude"], coords["latitude"])
)
end
table.insert(kml, ' </Document>\n</kml>\n')
kml = table.concat(kml, "\n")
local f = io.open(path, "w")
if not f then
return false, ("Failed to open file '%s'."):format(path)
end
if not f:write(kml) then
return false, ("Failed to write file '%s'."):format(path)
end
f:close()
return true, ("The map has been saved at '%s'."):format(path)
end
local parse_args = function()
local map_path = stdnse.get_script_args(SCRIPT_NAME .. '.map_path')
if not map_path then
return false, "Need to specify a path for the map."
end
return true, map_path
end
postrule = function()
-- Only run if a previous script has registered geolocation data.
return not geoip.empty()
end
action = function()
-- Parse and sanity check the command line arguments.
local status, path = oops.raise(
"Script argument problem",
parse_args())
if not status then
return path
end
-- Render the map.
return oops.output(render(path))
end
|