如何腌制 scapy 包?

发布于 2024-10-02 11:02:48 字数 88 浏览 9 评论 0原文

我需要腌制一个 scapy 数据包。大多数时候这是有效的,但有时pickler会抱怨函数对象。根据经验:ARP 数据包可以很好地腌制。某些 UDP 数据包有问题。

I need to pickle a scapy packet. Most of the time this works, but sometimes the pickler complains about a function object. As a rule of thumb: ARP packets pickle fine. Some UDP packets are problematic.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

拥抱我好吗 2024-10-09 11:02:49

我的解决方案(受到 scapy 邮件列表的启发)如下:

class PicklablePacket:
    """A container for scapy packets that can be pickled (in contrast
    to scapy packets themselves)."""
    def __init__(self, pkt):
        self.contents = bytes(pkt)
        self.time = pkt.time

    def __call__(self):
        """Get the original scapy packet."""
        pkt = scapy.Ether(self.contents)
        pkt.time = self.time
        return pkt

任何我希望通过 Queue 传递 scapy Packet 的地方,我只需包装它在 PicklablePacket 中,然后 __call__ 。我不知道没有以这种方式保留的数据。然而,这种方法仅适用于以太网数据包。 (在常规 NIC(而非 WLAN)上嗅探的所有数据包都是以太网。)它也可能扩展到其他类型。

My solution (as inspired by the scapy mailing list) is as follows:

class PicklablePacket:
    """A container for scapy packets that can be pickled (in contrast
    to scapy packets themselves)."""
    def __init__(self, pkt):
        self.contents = bytes(pkt)
        self.time = pkt.time

    def __call__(self):
        """Get the original scapy packet."""
        pkt = scapy.Ether(self.contents)
        pkt.time = self.time
        return pkt

Anywhere I wish to pass a scapy Packet through a Queue I simply wrap it in a PicklablePacket and __call__ it afterwards. I am not aware of data that is not retained this way. However this approach only works with Ethernet packets. (All packets sniffed on a regular NIC (not WLAN) are Ethernet.) It could probably be extended to work for other types, too.

美煞众生 2024-10-09 11:02:49

如果 pickle 指的是一般序列化,则始终可以使用 pcap 导入/导出方法: rdpcap和wrpcap

wrpcap("pkt.pcap",pkt)
pkt = rdpcap("pkt.pcap")

或者您可以启动您的进程并在另一个进程中抓取数据包。如果有某种模式可以匹配,比如已知端口或源 IP tcpdump 就可以工作:

tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\)

然后您可以读取生成的 pcap,如上所示:

pkts = rdpcap('FOO.pcap')

If by pickle you mean generically serialize you can always use the pcap import/export methods: rdpcap and wrpcap.

wrpcap("pkt.pcap",pkt)
pkt = rdpcap("pkt.pcap")

Or you could start up your process and grab the packets in another process. If there is some pattern you can match, say a known port or source IP tcpdump will work:

tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\)

You can then read the generated pcap in as above:

pkts = rdpcap('FOO.pcap')
难忘№最初的完美 2024-10-09 11:02:49

(This is more for reference, so no votes expected)

The Scapy list [email protected] is well-monitored and tends to be very responsive. If you don't get answers here, try there as well.

娇纵 2024-10-09 11:02:49

受此问题的启发,可以使用dill 库(或其他类似 sPickle 等 - 请参阅 pypi search pickle)来保存 scapy 数据包。例如,使用 sudo easy_install dill 或 sudo pip install dill 安装 dill。这是一个基本的使用场景:

import dill as pickle
# E.g. Dump an array of packets stored in variable mypackets to a file
pickle.dump(mypackets, open('mypackets.dill-pickle', 'w'))
# Restore them from the file
mypackets = pickle.load(open('mypackets.dill-pickle', 'rb'))

当然,如果只有一组数据包,也可以使用 scapy 的本机函数将数据包转储到 pcap 文件(可由 tcpdump/wireshark 等读取):

wrpcap("packets_array.pcap",packets_array)

As inspired by this question one can use the dill library (or others like sPickle etc - see pypi search pickle) to save scapy packets. E.g. Install dill using sudo easy_install dill or sudo pip install dill. Here's a basic usage scenario:

import dill as pickle
# E.g. Dump an array of packets stored in variable mypackets to a file
pickle.dump(mypackets, open('mypackets.dill-pickle', 'w'))
# Restore them from the file
mypackets = pickle.load(open('mypackets.dill-pickle', 'rb'))

Also one can of course just use scapy's native functions to dump the packets to a pcap file (readable by tcpdump/wireshark etc) - if one just has an array of packets:

wrpcap("packets_array.pcap",packets_array)
寻找我们的幸福 2024-10-09 11:02:49

您可以对 Packet 类进行 Monkeypatch,并注入 __getstate____setstate__ 方法,将对象中的函数从可选取表示形式转换为可选取表示形式。有关详细信息,请参阅此处

def packet_getstate(self):
    # todo

def packet_setstate(self, state):
    # todo

from scapy.packet import Packet
Packet.__getstate__ = packet_getstate
Packet.__setstate__ = packet_setstate

You can monkeypatch the Packet class and inject __getstate__ and __setstate__ methods that convert the function in the object from and to a picklable representation. See here for details.

def packet_getstate(self):
    # todo

def packet_setstate(self, state):
    # todo

from scapy.packet import Packet
Packet.__getstate__ = packet_getstate
Packet.__setstate__ = packet_setstate
掩饰不了的爱 2024-10-09 11:02:49

要使 PicklabePacket 类与 scapy 3.0.0 一起使用,您可以使用此类定义:

class PicklablePacket:
"""A container for scapy packets that can be pickled (in contrast
to scapy packets themselves).
This works for python 3.5.1 and scapy 3.0.0 """

def __init__(self, pkt):
    self.__contents = pkt.__bytes__()
    self.__time = pkt.time

def __call__(self):
    """Get the original scapy packet."""
    pkt = scapy.all.Ether(self.__contents)
    pkt.time = self.__time
    return pkt

To get the PicklabePacket class to work with scapy 3.0.0 you can use this class definition:

class PicklablePacket:
"""A container for scapy packets that can be pickled (in contrast
to scapy packets themselves).
This works for python 3.5.1 and scapy 3.0.0 """

def __init__(self, pkt):
    self.__contents = pkt.__bytes__()
    self.__time = pkt.time

def __call__(self):
    """Get the original scapy packet."""
    pkt = scapy.all.Ether(self.__contents)
    pkt.time = self.__time
    return pkt
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文