我正在创建一个开源框架,其中包含一些同事来测试软件,恶意软件,病毒等文件。我们希望采用我们捕获的出站连接并将它们绘制在世界地图上。我已经能够生成地图,并从地图上的文本文件中绘制数据。每次扫描时都会自动生成文本文件。我们永远不会知道该文件中的IP地址。有办法:
1)如何使用从数据库中提取到地图上的信息生成图例? (IP地址,国家,Ciy)
2)有没有办法让每个点的颜色不同?
3)有没有办法显示从地图上的连接开始到结束的连接线?
#!/usr/bin/env python
# by Angelis Pseftis 5/17/2015
from __future__ import print_function, unicode_literals, with_statement
import argparse
import contextlib
import requests
import sys
import csv
import matplotlib
# Anti-Grain Geometry (AGG) backend so GeoIP can be used 'headless' because Josh hates GUIs.'
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import GeoIP
def get_ip(ip_file):
"""
Returns a list of IP addresses from a file containing one IP per line.
"""
with contextlib.closing(ip_file):
return [line.strip() for line in ip_file]
def get_lat_lon(ip_list=[], lats=[], lons=[]):
"""
This function connects to the FreeGeoIP web service to get info from
a list of IP addresses.
Returns two lists (latitude and longitude).
"""
print("Processing {} IPs...".format(len(ip_list)))
for ip in ip_list:
r = requests.get("https://freegeoip.net/json/" + ip)
json_response = r.json()
print("{ip}, {region_name}, {country_name}, {latitude}, {longitude}".format(**json_response))
if json_response['latitude'] and json_response['longitude']:
lats.append(json_response['latitude'])
lons.append(json_response['longitude'])
return lats, lons
def geoip_lat_lon(gi, ip_list=[], lats=[], lons=[]):
"""
This function uses the MaxMind library and databases to geolocate IP addresses
Returns two lists (latitude and longitude).
"""
print("Processing {} IPs...".format(len(ip_list)))
for ip in ip_list:
try:
r = gi.record_by_addr(ip)
except Exception:
print("Unable to locate IP: %s" % ip)
continue
if r is not None:
print("%s {country_code} {latitude}, {longitude}".format(**r) % ip)
lats.append(r['latitude'])
lons.append(r['longitude'])
return lats, lons
def get_lat_lon_from_csv(csv_file, lats=[], lons=[]):
"""
Retrieves the last two rows of a CSV formatted file to use as latitude
and longitude.
Returns two lists (latitudes and longitudes).
Example CSV file:
119.80.39.54, Beijing, China, 39.9289, 116.3883
101.44.1.135, Shanghai, China, 31.0456, 121.3997
219.144.17.74, Xian, China, 34.2583, 108.9286
64.27.26.7, Los Angeles, United States, 34.053, -118.2642
"""
with contextlib.closing(csv_file):
reader = csv.reader(csv_file)
for row in reader:
lats.append(row[-2])
lons.append(row[-1])
return lats, lons
def generate_map(output, lats=[], lons=[]):
"""
Using Basemap and the matplotlib toolkit, this function generates a map and
puts a red dot at the location of every IP addresses found in the list.
The map is then saved in the file specified in `output`.
"""
print("Generating map and saving it to {}".format(output))
m = Basemap(projection='cyl', resolution='l')
m.bluemarble()
x, y = m(lons, lats)
m.scatter(x, y, s=1, color='#ff0000', marker='o', alpha=0.3)
plt.savefig(output, dpi=300, bbox_inches='tight')
def main():
parser = argparse.ArgumentParser(description='Visualize community on a map.')
parser.add_argument('-i', '--input', dest="input", type=argparse.FileType('r'),
help='Input file. One IP per line or, if FORMAT set to \'csv\', CSV formatted file ending with latitude and longitude positions',
default=sys.stdin)
parser.add_argument('-o', '--output', default='output.png', help='Path to save the file (e.g. /tmp/output.png)')
parser.add_argument('-f', '--format', default='ip', choices=['ip', 'csv'], help='Format of the input file.')
parser.add_argument('-s', '--service', default='f', choices=['f','m'], help='Geolocation service (f=FreeGeoIP, m=MaxMind local database)')
parser.add_argument('-db', '--db', default='./GeoLiteCity.dat', help='Full path to MaxMind database file (default = ./GeoLiteCity.dat)')
args = parser.parse_args()
output = args.output
if args.format == 'ip':
ip_list = get_ip(args.input)
if args.service == 'm':
gi = GeoIP.open(args.db, GeoIP.GEOIP_STANDARD)
lats, lons = geoip_lat_lon(gi, ip_list)
else: # default service
lats, lons = get_lat_lon(ip_list)
elif args.format == 'csv':
lats, lons = get_lat_lon_from_csv(args.input)
generate_map(output, lats, lons)
if __name__ == '__main__':
main()