GeoIP2 是一个强大的离线数据库,该数据库内定义并记录了目前所有主机的IP地址和所在位置,通过传入某个IP地址,即可精确的定位到主机的位置,再结合谷歌地图可完美的画出坐标。
IP地址精准识别: 通过wireshark
抓取pcap数据包,然后使用geoip2
模块实现对IP地址的精准解析。
模块下载地址: https://github.com/maxmind/GeoIP2-python 离线数据库:https://www.maxmind.com/en/accounts/current/geoip/downloads
GeoIP2简单的定位使用案例。
代码语言:javascript复制>>> 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()
完整代码。
代码语言:javascript复制#coding=utf-8
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)
# print("[ ] 源地址: %-16s --> 目标地址: %-16s"%(src,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
代码语言:javascript复制#coding=utf-8
# pip install python-geoip-geolite2
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)
# print("[ ] 源地址: %-16s --> 目标地址: %-16s"%(src,dst))
ret.append(dst)
except:
pass
return set(ret)
def retKML(addr,longitude,latitude):
kml = (
'<Placemark>n'
'<name>%s</name>n'
'<Point>n'
'<coordinates>o,o</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()