IP List to KML generator (Create a google map from a list of IPs)

Pretty simple, it takes a file with a list of ips, one/line and generates a kml file. Very handy if you’re working on a large pentest and want to track down (and visualize) where a particular host is located. It uses the Yahoo GeoIP API to grab location data.

#!/usr/bin/ruby

require 'net/http'
require 'rexml/document'

include REXML

def getAddress(ip)
#takes an ip and returns an xml blob with city/state
# example: http://ipinfodb.com/ip_query.php?ip=65.23.23.33
 url = "http://ipinfodb.com/ip_query.php?ip=" + ip
 #puts "DEBUG: URL: #{url.to_s}"
 resp = Net::HTTP.get(URI.parse(url))
 #print "DEBUG: got " + resp
return resp
end

def getCoordinates(address)
#takes a hash with city, state address and returns a hash w/ coords
url = "http://local.yahooapis.com/MapsService/V1/geocode"
 params = {
 "appid" => "GwLDY.bV34HH7gkBDs97p_5U5P_tBfXBnfDyYFwpTRLwZDEvgj8BOQqws1JOCFPyhTQR",
 "street" => "",
 "city" => address["city"],
 "state" => address["state"]
 }
 #puts "DEBUG: URL: #{url.to_s}"
 resp = Net::HTTP.post_form(URI.parse(url), params)
 resp_text = resp.body
 #print "DEBUG: got " + resp_text
return resp_text
end

def parseAddress(xml)
#takes an xml blob with city / state & returns a hash with address,city,state
 doc = Document.new xml
 root = doc.root

 city = root.elements["City"].get_text.to_s
 state = root.elements["RegionName"].get_text.to_s
 country = root.elements["CountryCode"].get_text.to_s

 #puts "DEBUG: city: " + city
 #puts "DEBUG: state: " + state
 #puts "DEBUG: country: " + country

 toReturn = Hash["city" => city, "state" => state, "country" => country]
 return toReturn
end

def parseCoordinates(xml)
#takes an xml blob with coordinates & returns a hash with long/lat
 doc = REXML::Document.new xml
 root = doc.root

 long = REXML::XPath.first( doc, "//Longitude" ).get_text.to_s
 lat = REXML::XPath.first( doc, "//Latitude" ).get_text.to_s

 toReturn = Hash["long" => long, "lat" => lat]

 #puts "DEBUG: long: " + long
 #puts "DEBUG: lat: " + lat

 return toReturn
end

def genKML(ips)
 kml = ""
 kml = kml + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 kml = kml + "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
 kml = kml + "<Document>\n"
 ips.each do |ip|
 ip = ip.to_s.chomp
 kmlplacemark = mip(ip,"error.log")

 if kmlplacemark.to_s != "" then
 #        puts "DEBUG: adding non-blank placemark" + kmlplacemark
 kml = kml + kmlplacemark
 else
 #        puts "DEBUG: unable to map ip: " + ip + "\n"
 end
 end

 kml = kml + "</Document>\n"
 kml = kml + "</kml>\n"
end

def genPlacemark(ip,address,coordinates)
 xml = ""
 xml = xml + "    <Placemark>\n"
 xml = xml + "        <name>" + ip + "</name>\n"
 xml = xml + "        <description>"
 xml = xml + address["city"] + ", "
 xml = xml + address["state"] + ", "
 xml = xml + address["country"]
 xml = xml + "</description>\n"
 xml = xml + "        <Point>\n"
 xml = xml + "            <coordinates>" +
 coordinates["long"]  + "," +
 coordinates["lat"] + ",0</coordinates>\n"
 xml = xml + "        </Point>\n"
 xml = xml + "    </Placemark>\n"
end


def mip(ip,errorfile)
 begin
 if (ip != "") then
 xmlAddress = getAddress(ip)
 objAddress = parseAddress(xmlAddress)

 if (objAddress["state"] != "") then
 xmlCoordinates = getCoordinates(objAddress)
 objCoordinates = parseCoordinates(xmlCoordinates)

 kmlplacemark = genPlacemark(ip,objAddress,objCoordinates)
 else
 File.open(errorfile, 'w') {|f| f.write(ip) }

 end
 end
 rescue
 kmlplacemark = ""
 end

return kmlplacemark
end

def mips(file)
 counter = 0
 ips = Array.new

 File.open(file, "r") do |infile|

 while (line = infile.gets)
 #puts "mapping #{counter}: #{line}"

 ips[counter] = line

 counter = counter + 1
 end
 end
 kml = genKML(ips)
 return kml
end


kml = mips(ARGV[0])
out = File.new(ARGV[0]+".kml", "w")
out.puts kml

1 Comment

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s