Python使用scapy和dpkt抓包并解析

scapy

scapy是python中一个可用于网络嗅探的非常强大的第三方库,可以用它来做 packet 嗅探和伪造 packet。 scapy已经在内部实现了大量的网络协议。如DNS、ARP、IP、TCP、UDP等等,可以用它来编写非常灵活实用的工具。

scapy安装:

pip install scapy 

安装完后: 

ls()  命令可以查看所有支持的协议
ls(IP) 命令列出ip协议头部字段格式,只要想查看哪个协议的参数,括号里就填哪个协议
IP().show() 列出ip包的信息
lsc() 命令列出scapy的所有命令 
conf 命令列出scapy 的配置参数

scapy抓包使用 sniff() 函数,这个函数有很多参数:

def sniff(count=0, store=1, offline=None, prn=None,filter=None, L2socket=None, timeout=None, opened_socket=None, stop_filter=None, iface=None,*args,**kargs)

  • count:抓包的数量,0表示无限制;
  • store:保存抓取的数据包或者丢弃,1保存,0丢弃
  • offline:从 pcap 文件读取数据包,而不进行嗅探,默认为None
  • prn:为每一个数据包定义一个函数,如果返回了什么,则显示。例如:prn = lambda x: x.summary(); (  packct.summar()函数返回的是对包的统计性信息 )
  • filter:过滤规则,使用wireshark里面的过滤语法
  • L2socket:使用给定的 L2socket
  • timeout:在给定的时间后停止嗅探,默认为 None
  • opened_socket:对指定的对象使用 .recv() 进行读取;
  • stop_filter:定义一个函数,决定在抓到指定数据包后停止抓包,如:stop_filter = lambda x: x.haslayer(TCP);
  • iface:指定抓包的接口 

 使用scapy抓包:

from scapy.all import *

# scapy抓包:
def catch_pack():
    sniff(prn=printPacket,filter="tcp")

# 抓包监听
def printPacket(packet):
    wrpcap('foo.pcap', [packet])

dpkt

dpkt是一个python模块,可以对简单的数据包创建/解析,以及基本TCP / IP协议的解析,速度很快。

dpkt读取每个pcap包里的内容,用isinstance判断是不是有IP的包,再判断是属于哪个协议,对应的协议已经封装好API如果发现可以匹配某个协议API就输出来相关值。

dpkt — dpkt 1.9.2 documentationhttps://dpkt.readthedocs.io/en/latest/

dpkt安装:

pip install dpkt

 使用dpkt解包:

# dpkt解包
def decodePacket(timestamp, packet_data):
    packet = dpkt.ethernet.Ethernet(packet_data)
    if not isinstance(packet.data, dpkt.ip.IP):
        return
    if not isinstance(packet.data.data, dpkt.tcp.TCP):
        return
    httpData = packet.data.data.data
    if len(httpData) < 4:
        return
    req = dpkt.http.Request(httpData)
    headers = {}
    for k,v in req.headers.items():
        headers[k] = v
    print("request+++>timestamp:",timestamp)
    print("request+++>headers:",headers)
    print("request+++>method:", req.method)
    print("request+++>uri:", req.uri)
    print("request+++>body:", req.body)
    try:
        response = dpkt.http.Response(httpData) # 尝试以HTTP读取响应
        print("response:",response)
    except:
        print("decode http response error")
def readPacket(packet):
    try:
        with open('foo.pcap', 'rb') as f:
            capture = dpkt.pcap.Reader(f)
            for timestamp, packet in capture: # 键值对,提取packet进行解码
                decodePacket(timestamp, packet)
    except:
        pass

你可能感兴趣的:(Python,python,1024程序员节)