目录

流量处理工具

SplitCap

EditCap

tshark

tcpreplay

PYTHON库

Scapy

DPKT

pcap-ct

flowcontainer


流量处理工具

  • SplitCap

    SplitCap.exe -r test.pcap -s session -o ./split_pcaps
    
    -r: 读取pcap
    -s: 切分方式,session为按会话切分
    -o: 输出文件夹路径
  • EditCap

    • 官方链接:editcap(1)

    • 平台:win平台,同wireshark一起安装,一般在同目录下。
    • 功能:切割pcap,按包数、包长等。
    • 示例: 
    editcap.exe -F pcap -c 1000 src.pcap dst.pcap
    
    editcap.exe -F pcap -i 10 src.pcap dst.pcap
    
    -F: 输出格式,默认为pcapng
    -c: 按n个包切分
    -i: 按n秒间隙分割
    src.pcap: 源pcap包
    dst.pcap: 输出pcap包名,会按此格式生成切分后的若干个pcap包
  • tshark

    • 官方连接:tshark(1)
    • 平台:win,linux;win下同wireshark一起安装,一般在同目录下。
    • 功能:提取pcap中每个数据包的指定字段。该工具速度快,功能强大,可应付大部分流量处理场景,值得深入学习。
    • 示例:
    tshark -r src.pcap -T fields -e frame.len -e ip.proto -e tcp.srcport -E header=y > dst.csv
    
    -e 指明需要提取的字段
    -e frame.time_relative 包的相对时间
    -e ip.src 源IP
    -e ip.dst 目的IP
    -e ip.proto 协议名
    -e tcp.srcport 源Port
    -e tcp.dstport 目的Port
    -e frame.len 包大小
    -E header=n 是否输出表头

        参考:网络分析利器:Tshark - 简书

tcpreplay -i ens33 -l 1 -t test.pcap

-i:网卡名
-t:最高速度回放
-l:循环次数
-p:以每秒多少包的速度回放
-x:以捕获速度的倍数重放

        

PYTHON库

以下各个库功能主要以读取、处理pcap文件实时监听网卡并抓包为主。

  • Scapy

官方文档:介绍 — Scapy 2.4.4. 文档

优点:简单易上手

缺点:速度非常慢,执行rdpcap时会将整个pcap读入内存,因此读取超大pcap时需配合splitcap、editcap等工具或PcapReader(下文)共同使用。

from scapy.all import *

# 读取pcap文件
packets = rdpcap('test.pcap')    # packets = rdpcap('test.pcap', 200)

# 遍历数据包
for packet in packets:

    # 若当前包不包含DNS协议,跳过
    if 'DNS' not in packet:
        continue

    # 若当前DNS报文不包含DNS问题记录,跳过
    if 'DNS Question Record' not in packet['DNS']:
        continue

    # 若DNS报文的qr字段为1(响应报文),则打印该报文需要回复的域名
    if packet['DNS'].qr == 1:
        print(packet['DNS']['DNS Question Record'].qname)

注:

1. rdpcap方法可传入第二个参数(int),指定读取数据条数,若设置较小,可极大提升读取速度。

2. 执行packet.show()会输出当前packet所有可访问字段和值,可为程序读取提供参考。

超大PCAP:使用scapy处理超大PCAP包时,可配合PcapReader逐个读取包。此方法可避免内存爆炸,但需要较长时间。

from scapy.all import *
load_layer("tls")


class PCAPProcessor:
    def __init__(self):
        pass
    
    # 依次读取超大pcap中的每个packet
    def yield_packet(self, src_file_path):
        with PcapReader(src_file_path) as pcap_reader:  # 返回一个迭代器
            for pkt in pcap_reader:  # for循环进行遍历
                yield pkt
    
    # 写入pcap
    def write_pkt(self, pkt, dst_file_path):
        wrpcap(dst_file_path, pkt, append=True)


if __name__ == '__main__':
    p = PCAPProcessor()
    g = p.yield_packet('./test.pcap')

    while True:
        try:
            pkt = next(g)
            
            # 此处调用处理每个packet的函数
        except Exception as e:
            break

参考:python3使用scapy分析修改pcap大文件(1G)_scapy切分大的pcap文件-CSDN博客

实时监听:Scapy也可以实时监听网卡,使用callback来处理监听到的每个包。

from scapy.all import *


def callback(packet):
    if packet.haslayer('HTTP'):
        http = packet.payload.payload.payload
        print(http.show())


sniff(prn=callback, iface='ens33', count=0)

  • DPKT

官方文档:dpkt — dpkt 1.9.2 documentation

优点:pcap读取速度远快于scapy。

缺点:使用相比scapy更繁琐,实时抓包的功能需要配合pcap-ct库使用。

import dpkt

# 读取pcap文件
with open('test.pcap', 'rb') as f:
    pcap = dpkt.pcap.Reader(f)
    
    # 遍历数据包
    for timestamp, buf in pcap:
        eth = dpkt.ethernet.Ethernet(buf)

        # 获取IP层,若当前包不存在IP层则continue
        if not isinstance(eth.data, dpkt.ip.IP):
            continue
        ip = eth.data

        # 获取UDP层,若当前包不存在UDP层则continue
        if not isinstance(ip.data, dpkt.udp.UDP):
            continue
        udp = ip.data

        # 将udp载荷读取为DNS报文
        try:
            dns = dpkt.dns.DNS(udp.data)
        except Exception as e:
            continue

        # 若DNS报文的qr字段为1(响应报文),则打印该报文需要回复的域名
        if dns.qr == 1:
            if len(dns.qd) > 0:
                print(dns.qd[0].name)
  • pcap-ct

可用于实时抓包,配合dpkt分析。

import dpkt
import pcap     # pcap-ct

sniffer = pcap.pcap(name='ens33', promisc=True, immediate=True, timeout_ms=50)

for ts, pkt in sniffer:
    eth = dpkt.ethernet.Ethernet(pkt)

    if not isinstance(eth.data, dpkt.ip.IP):
        continue
    ip = eth.data

    if not isinstance(ip.data, dpkt.tcp.TCP):
        continue
    tcp = ip.data

    # process the data
    print(tcp.flags)
  • flowcontainer

文档:GitHub - jmhIcoding/flowcontainer: 从pcap获取流的基本信息工具

功能:读入pcap文件生成多种流特征。

参考:flowcontainer: 基于python3的pcap网络流量特征信息提取库_Icoding_F2014的博客-CSDN博客

from flowcontainer.extractor import extract

result = extract(r"test.pcap",filter='',extension=["tls.handshake.extensions_server_name","tls.handshake.ciphersuite"])

for key in result:
    ### The return vlaue result is a dict, the key is a tuple (filename,procotol,stream_id)
    ### and the value is an Flow object, user can access Flow object as flowcontainer.flows.Flow's attributes refer.

    value = result[key]
    print('Flow {0} info:'.format(key))
    print('src ip:',value.src)
    print('dst ip:',value.dst)
    ## access payload packet lengths
    print('payload lengths :',value.payload_lengths)
    ## access payload packet timestamps sequence:
    print('payload timestamps:',value.payload_timestamps)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐