首页 > 编程语言 >21.4 Python 使用GeoIP2地图定位

21.4 Python 使用GeoIP2地图定位

时间:2023-10-24 19:05:04浏览次数:37  
标签:%- 21.4 Python data GeoIP2 __ print pcap response

GeoIP2是一种IP地址定位库,它允许开发人员根据IP地址查找有关位置和地理位置的信息。它使用MaxMind公司的IP地址数据库,并提供一个方便的Python API。GeoIP2可以用于许多不同的应用程序,例如网站分析、广告定位和身份验证。GeoIP2提供了许多不同的信息,例如国家、城市、邮政编码、经纬度、时区等等。它还可以使用IPv6地址进行查询。

  • 安装第三方库:pip install geoip2
  • GitHub地址:https://github.com/maxmind/GeoIP2-python
  • 离线数据库:https://www.maxmind.com/en/accounts/current/geoip/downloads

读者可自行执行pip install geoip2命令安装这个第三方库,并自行下载对应免费版本的GeoLite2-City.mmdb主机数据库文件,当一切准备就绪以后我们就可以使用该数据库定位位置了,如下代码是一个演示案例,首先通过GetPcap将数据包解析并存储值ret变量内返回,当返回后通过geoip2.database加载数据库文件,并通过循环的方式以此查询reader.city数据,并将详细地址输出。

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('d://lyshark.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地图模板,一般Google底部模板采用KML文件格式,如下这段代码则是生成一个对应的地图模板,通过传入所需分析的pcap数据包以及数据库信息,则可以输出一个GoogleEarth.kml模板文件。

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

此时打开谷歌地图,并选择左侧的项目菜单,选择从计算机中导入KML文件,并自行将googleearth.kml文件导入到地图文件内,如下图所示;

  • 谷歌地图:https://www.google.com/earth/

当导入成功后,此时在地图左侧将会出现一些坐标信息,此时读者可自行点击这些坐标以确定当前IP地址的详细位置,当然该地址仅供参考,因为某些主机的地址可能会使用隐藏IP的方式并不一定确保一定准确。

当然了上述代码只是一个演示案例,在实际过滤中我们可以会进行多层解析,例如如下这段代码,其中AnalysisIP_To_Address函数就可用于接收一个过滤规则,代码中dport ==80 or dport == 443则用于只过滤出目标端口是80443的主机信息,读者也可自行增加一条符合规则的过滤条件进行自定义捕捉,此处仅仅只是一个演示案例。

import argparse
import socket,dpkt
import geoip2.database

def AnalysisPace(DpktPack,Filter):
    respon = []
    with open(DpktPack,"rb") as fp:
        pcap = dpkt.pcap.Reader(fp)
        for timestamp, packet in pcap:
            try:
                eth = dpkt.ethernet.Ethernet(packet)
                # 解析过滤出网络层(三层)中的IP数据包
                if eth.data.__class__.__name__ == "IP":
                    ip = eth.data
                    src = socket.inet_ntoa(ip.src)
                    dst = socket.inet_ntoa(ip.dst)
                    # 解析过滤出传输层(四层)中的TCP数据包
                    if eth.data.data.__class__.__name__ == "TCP":
                        sport = eth.data.data.sport
                        dport = eth.data.data.dport
                        # 过滤出源地址是192.168.1.2且目的端口是80或者443的流量
                        # if src == "192.168.1.2" and dport == 80 or dport == 443:
                        if eval(Filter):
                            dic = { "src":"None","sport":0 , "dst":"None","dport":0 }
                            #print("[+] 时间戳: %-17s 源地址: %-14s:%-2s ---> 目标地址: %-16s:%-2s" %(timestamp,src, sport, dst, dport))
                            RecvData = eth.data.data.data
                            if len(RecvData) and b"GET" in RecvData:
                                #print("[*] 时间戳: {} 源地址: {} <--- 访问网页: {}".format(timestamp,src,bytes.decode(RecvData).split("\n")[1]))
                                pass
                            dic['src'] = src
                            dic['dst'] = dst
                            dic['sport'] = sport
                            dic['dport'] = dport
                            respon.append(dic)
            except Exception:
                pass
    return respon

def AnalysisIP_To_Address(PcapFile,MmdbFile):
    IPDict = AnalysisPace(PcapFile,"dport ==80 or dport == 443")
    NoRepeat = []

    for item in range(len(IPDict)):
        NoRepeat.append(IPDict[item].get("dst"))
    NoRepeat = set(NoRepeat)

    reader = geoip2.database.Reader(MmdbFile)
    for item in NoRepeat:
        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"],response.subdivisions.most_specific.name,response.city.name),end="\n")
        except Exception:
            print("定位: None None None")
            pass

if __name__ == '__main__':
    Banner()
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", "--pcap", dest="pcap", help="设置抓到的数据包 *.pcap")
    parser.add_argument("-d", "--mmdb", dest="mmdb", help="设置城市数据库 GeoLite2-City.mmdb")
    
    args = parser.parse_args()
    # 使用方式: main.py -p data.pcap -d GeoLite2-City.mmdb (分析数据包中IP)
    if args.pcap and args.mmdb:
        AnalysisIP_To_Address(args.pcap,args.mmdb)
    else:
        parser.print_help()

本文作者: 王瑞 本文链接: https://www.lyshark.com/post/647f46e.html 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

标签:%-,21.4,Python,data,GeoIP2,__,print,pcap,response
From: https://blog.51cto.com/lyshark/8009087

相关文章

  • 基于Python的子进程获取键盘输入
    一概念 众所周知,python中的获取键盘输入,input函数是没办法用在子程序的,这就限制了它的用途。想要在子程序中获取键盘输入。唯有fn=sys.stdin.fileno函数了。二实例解析在主进程中敲写代码fn=sys.stdin.fileno(),然后将获取到的文件描述符fn传入子进程,子进程敲写代码sys......
  • python selenium 利用pyautogui+ActionChains 完美解决我的滑块验证登录问题
    在解决滑块验证的时候不知道什么原因明明是滑块已经对上了,代码执行就是会校验不通过,手动时就可以,中间也做利用ActionChains模块减速滑动轨迹的操作,但仍然不行,后面在执行代码中添加了pyautogui模块使鼠标悬停在屏幕中的某个点而不改变ActionChains鼠标的定位后终于每次都能通过了fro......
  • 21.4 Python 使用GeoIP2地图定位
    GeoIP2是一种IP地址定位库,它允许开发人员根据IP地址查找有关位置和地理位置的信息。它使用MaxMind公司的IP地址数据库,并提供一个方便的PythonAPI。GeoIP2可以用于许多不同的应用程序,例如网站分析、广告定位和身份验证。GeoIP2提供了许多不同的信息,例如国家、城市、邮政编码、经纬......
  • Python数据类型
     数据类型有数值型,布尔型和字符串型一、数值型包括int(整型)、float(浮点型)和complex(复数型)等。1.整型Python3.x支持任意大小的整型数。整型数可以表示成十进制、八进制、十六进制和二进制形式。十进制整型常量:数码为0~9,如-135、57232。八进制整型常量:必须以80或8o开头(第1......
  • python引用相对路径
    文件夹ants/bees文件夹与learn_data.py隶属于同一个目录data_process   所以引用相对路径的方式即为:classMyData(Dataset):def__init__(self,root_dir,label_dir):self.root_dir=root_dir#根目录,即hymenoptera_data/trainself.label_......
  • python当前工作目录和当前文件的绝对路径
    当前文件的绝对路径:这个就是文件在硬盘上的真实路径,从盘符一直到文件所在的具体位置。当前工作目录(currentworkingdirectory)是文件系统当前所在的目录,如果命令没有额外指定路径,则默认为当前工作目录。    importos#当前文件的绝对路径print(os.path.abspath(......
  • python 网络编程
    python编程目录python编程一.网络编程socket1.1基于tcp实现网络通讯1.2基于tcp实现远程执行命令1)粘包问题2)自定义协议解决粘包问题3)最终版定义字典解决粘包问题1.3socketserver实现并发1)基于TCP实现2)基于UDP实现一.网络编程socket1.1基于tcp实现网络通讯服务......
  • 关于Python正则式中的r和字符串中的r
     正则表达式也是字符串,但是不是普通的字符串,其中包含了正则转义和字符串转义。正则表达式前边加r是取消了字符串转义,但是正则转义还在。例1和例2的对比中,例2的正则表达式取消了普通字符串转义,但是\n在正则表达式里是匹配换行符。例2和例3的对比中,例3的被匹配对象实际是两个字......
  • python 解析User-Agent
    需求:从User-Agent中获取浏览器信息和操作系统信息使用第三方库ua-parser安装pipinstallua-parser使用fromua_parser.user_agent_parserimportParse#解析user_agentparsed_user_agent=Parse(user_agent)print(parsed_user_agent)返回数据{"string":"Mozill......
  • Python打包为可执行exe
    为什么要打包exe有的时候只需要让别人运行某种功能,传输文件以及代码是需要别人配置好一定的环境才可以操作,而打包成exe文件就可以直接运行文件。pyinstaller打包python中常用的打包方式首先进行pyinstaller的安装,打开cmd输入pipinstallpyinstaller-ihttp://pypi.douban.c......