当前位置: 首页 > 工具软件 > open-geoip > 使用案例 >

Python 运用GeoIP2离线数据库定位

糜昌胤
2023-12-01

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()

完整代码。

#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

#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>%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()
 类似资料: