在网络分析和数据恢复的场景中,我们经常需要从 .pcap 文件中提取原始数据部分,而不是完整的数据包信息(包括网卡信息、协议头等)。本文将介绍几种方法来高效地从 .pcap 文件提取 原生的二进制数据 并保存到文件中。


1. 使用 scapy 提取原生数据

scapy 是一个强大的 Python 网络数据处理库,它可以轻松解析 .pcap 文件并提取有效负载(Payload)。以下代码展示了如何读取 .pcap 文件,并将 TCP 数据包中的有效负载 直接保存为二进制文件:

from scapy.all import rdpcap

# 读取 pcap 文件
packets = rdpcap('file.pcap')

with open('output.bin', 'wb') as f:
    for packet in packets:
        # 检查是否是 TCP 数据包,并且包含 Raw 负载
        if packet.haslayer('TCP') and packet.haslayer('Raw'):
            payload = packet['Raw'].load  # 提取原始负载
            f.write(payload)  # 写入二进制文件

说明

  • rdpcap('file.pcap') 读取 .pcap 文件中的所有数据包。
  • packet.haslayer('Raw') 检查数据包是否包含有效负载(应用层数据)。
  • packet['Raw'].load 获取原始二进制数据。
  • f.write(payload) 将二进制数据写入 output.bin 文件,不做任何转换。

这个方法适用于大多数 TCP 数据流,特别是当你想从捕获的流量中恢复文件或其他二进制数据时。


2. 使用 pyshark 提取 TCP 有效负载

pyshark 是 Wireshark 的 Python 接口,它可以解析 .pcap 文件并提取数据。以下代码展示了如何使用 pyshark 读取 .pcap 并提取 TCP 数据包的有效负载:

import pyshark

# 打开 pcap 文件
cap = pyshark.FileCapture('file.pcap', only_summaries=False)

with open('output.bin', 'wb') as f:
    for packet in cap:
        # 检查是否是 TCP 包,并且包含有效负载
        if 'TCP' in packet and hasattr(packet, 'tcp') and hasattr(packet.tcp, 'payload'):
            # 将十六进制字符串转换为原始字节
            payload = bytes.fromhex(packet.tcp.payload.replace(":", ""))
            f.write(payload)  # 写入二进制文件

说明

  • pyshark.FileCapture('file.pcap') 读取 .pcap 文件并解析每个数据包。
  • packet.tcp.payload 获取 TCP 层的有效负载,但它是十六进制字符串格式。
  • bytes.fromhex(packet.tcp.payload.replace(":", "")) 将十六进制字符串转换为字节格式,以便写入文件。

这种方法的优势是 pyshark 能够提供更详细的协议解析能力,适用于复杂的 .pcap 解析任务。


3. 使用 Go 语言(gopacket 库)

如果你更喜欢使用 Go 语言,可以使用 gopacket 库来读取 .pcap 文件并提取应用层数据。

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/google/gopacket"
    "github.com/google/gopacket/pcap"
)

func main() {
    // 打开 pcap 文件
    handle, err := pcap.OpenOffline("file.pcap")
    if err != nil {
        log.Fatal(err)
    }
    defer handle.Close()

    // 创建输出文件
    outFile, err := os.Create("output.bin")
    if err != nil {
        log.Fatal(err)
    }
    defer outFile.Close()

    // 处理每个数据包
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        // 获取应用层负载
        if appLayer := packet.ApplicationLayer(); appLayer != nil {
            outFile.Write(appLayer.Payload()) // 写入原始有效负载
        }
    }

    fmt.Println("数据提取完毕")
}

说明

  • pcap.OpenOffline("file.pcap") 打开 .pcap 文件。
  • packet.ApplicationLayer() 提取应用层数据(通常是 TCP 或 UDP 的有效负载)。
  • outFile.Write(appLayer.Payload()) 将原始负载写入二进制文件。

这个方法非常高效,适用于大规模 .pcap 文件处理。


4. 使用 tcpdump(命令行工具)

如果你不想编写代码,也可以使用 tcpdump 提取数据包并保存为二进制文件:

tcpdump -r file.pcap -nn -s 0 -w output.bin

说明

  • -r file.pcap 读取 .pcap 文件。
  • -nn 关闭 DNS 解析,加快处理速度。
  • -s 0 确保捕获整个数据包(否则可能会截断)。
  • -w output.bin 将数据包写入二进制文件。

注意tcpdump 这种方式会包含完整的数据包(包括头部信息),如果你只需要有效负载,仍然需要额外处理。


5. 如何验证提取的二进制数据

在提取数据后,你可以使用 hexdumpxxd 命令检查 output.bin 是否符合预期:

hexdump -C output.bin | head -20

或者使用 xxd

xxd output.bin | head -20

如果你提取的是文件数据(如 HTTP 传输的图片或视频),你可以尝试用 file 命令检测:

file output.bin

总结

方法适用场景是否提取原始二进制
scapyPython 解析 .pcap 并提取 TCP 负载
pysharkPython 解析 .pcap,适用于详细协议分析
gopacketGo 语言处理大规模 .pcap 文件
tcpdump命令行提取数据包❌(包含头部)

如果你想要快速提取原生二进制数据

  • 推荐 scapypyshark(Python 用户)。
  • 推荐 gopacket(Go 用户)。
  • 命令行用户可以尝试 tcpdump,但需要进一步处理数据

通过以上方法,你可以轻松提取 .pcap 文件中的原始二进制数据,并进行后续分析或恢复。🚀

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注