GeoIP2 是一个强大的离线数据库,该数据库内定义并记录了目前所有主机的IP地址和所在位置,通过传入某个IP地址,即可精确的定位到主机的位置,再结合谷歌地图可完美的画出坐标。
IP地址精准识别: 通过wireshark
抓取pcap数据包,然后使用geoip2
模块实现对IP地址的精准解析。
模块下载地址: https://github.com/maxmind/GeoIP2-python
离线数据库:https://www.maxmind.com/en/accounts/current/geoip/downloads
GeoIP2简单的定位使用案例。
>>> import geoip2.database>>> reader = geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') >>> response = reader.city('128.101.101.101') >>> >>> response.country.iso_code 'US' >>> response.country.name 'United States' >>> response.country.names['zh-CN'] u'美国' >>> >>> response.subdivisions.most_specific.name 'Minnesota' >>> response.subdivisions.most_specific.iso_code 'MN' >>> >>> response.city.name 'Minneapolis' >>> >>> response.postal.code '55455' >>> >>> response.location.latitude 44.9733 >>> response.location.longitude -93.2323 >>> >>> response.traits.network IPv4Network('128.101.101.0/24') >>> >>> reader.close()
|
完整代码。
import dpkt import socket import geoip2.database
def GetPcap(pcap): ret = [] for timestamp,packet in pcap: try: eth = dpkt.ethernet.Ethernet(packet) ip = eth.data src = socket.inet_ntoa(ip.src) dst = socket.inet_ntoa(ip.dst) ret.append(dst) except: pass return set(ret)
if __name__ == '__main__': fp = open('data.pcap','rb') pcap = dpkt.pcap.Reader(fp) addr = GetPcap(pcap) reader = geoip2.database.Reader("d://GeoLite2-City.mmdb") for item in addr: try: response = reader.city(item) print("IP地址: %-16s --> " %item,end="") print("网段: %-16s --> " %response.traits.network,end="") print("经度: %-10s 纬度: %-10s --> " %(response.location.latitude, response.location.longitude),end="") print("地区: {}".format(response.country.names["zh-CN"]),end="\n") except Exception: pass
|
生成Google地图文件: 通过geoip2
模块定位后,生成google地图识别格式kml
文件。
接着访问谷歌地球 https://www.google.com/earth/ 直接将生成的googleearth.kml 导入即可完成定位.
也可使用离线版地图: https://dl.google.com/dl/earth/client/advanced/current/googleearthprowin-7.3.2.exe
import dpkt import socket import geoip2.database from optparse import OptionParser
def GetPcap(pcap): ret = [] for timestamp,packet in pcap: try: eth = dpkt.ethernet.Ethernet(packet) ip = eth.data src = socket.inet_ntoa(ip.src) dst = socket.inet_ntoa(ip.dst) ret.append(dst) except: pass return set(ret)
def retKML(addr,longitude,latitude): kml = ( '<Placemark>\n' '<name>%s</name>\n' '<Point>\n' '<coordinates>%6f,%6f</coordinates>\n' '</Point>\n' '</Placemark>\n' ) %(addr, longitude, latitude) return kml
if __name__ == '__main__': parser = OptionParser() parser.add_option("-p", "--pcap", dest="pcap_file", help="set -p *.pcap") parser.add_option("-d", "--mmdb", dest="mmdb_file", help="set -d *.mmdb") (options, args) = parser.parse_args() if options.pcap_file and options.mmdb_file: fp = open(options.pcap_file,'rb') pcap = dpkt.pcap.Reader(fp) addr = GetPcap(pcap) reader = geoip2.database.Reader(options.mmdb_file)
kmlheader = '<?xml version="1.0" encoding="UTF-8"?>\ \n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n' with open("GoogleEarth.kml", "w") as f: f.write(kmlheader) f.close()
for item in addr: try: response = reader.city(item) print("IP地址: %-16s --> " %item,end="") print("网段: %-16s --> " %response.traits.network,end="") print("经度: %-10s 纬度: %-10s --> " %(response.location.latitude, response.location.longitude),end="") print("地区: {}".format(response.country.names["zh-CN"]),end="\n")
with open("GoogleEarth.kml","a+") as f: f.write(retKML(item,response.location.latitude, response.location.longitude)) f.close() except Exception: pass
kmlfooter = '</Document>\n</kml>\n' with open("GoogleEarth.kml", "a+") as f: f.write(kmlfooter) f.close() else: parser.print_help()
|