为什么使用Python 2打印scapy.layers.l2.Ether对象,我获得了预期的结果,而使用Python 3打印它,却得到了这个奇怪的输出?

问题描述 投票:0回答:1

我是Python的初学者,如果我使用Python 3而不是Python 2执行该程序,则会在程序中发现以下奇怪行为。

我将尝试详细解释这种情况。

我在计算机上安装了这两个版本的Python:

  • Python 2.7.17
  • Python 3.7.7

然后我使用Scapy使用此脚本:

#!usr/bin/env python

# INSTALL THE FOLLOWING PYTHON MODULES:
# - pip3 install scapy
# - pip3 install scapy_http

import scapy.all as scapy
from scapy.layers import http

#
def sniff(interface):
    # iface: specify the interface used to sniff on.
    # store: I tell scapy to not store packets in memory.
    # prn: allows to specify a callback function (a function that is call every time that the sniff() function sniff
    #      a packet.
    # OPTIONAL FILTERS: uses to specifies filters packets using "BPF syntax"
    #         SOME FILTER EXAMPLES:
    #           - udp: filter UDP packets
    #           - arp: filter ARP packets
    #           - tcp: filter TCP packets
    #           - port 21: filter packets on a specific port
    # DOCUMENTATION LINK: https://scapy.readthedocs.io/en/latest/extending.html
    #scapy.sniff(iface=interface, store=False, prn=process_sniffed_packet, filter=80)
    scapy.sniff(iface=interface, store=False, prn=process_sniffed_packet)


def process_sniffed_packet(packet):
    #print(packet)
    # Check if our packet has HTTP layer. If our packet has the HTTP layer and it is HTTPRequest.
    # In this way I am excluding some garbage information in which I am not interested into.
    if packet.haslayer(http.HTTPRequest):
        print(packet)
        print("-------------------------------------")
        #print(packet.decode("utf-8"))
        print(type(packet))


sniff("eth0")

此脚本通过HTTP协议实现了简单的流量嗅探器。

[[Python 2使用的scapy的版本应该是这个:

root@kali:~/Documents/PycharmWS/packet_sniffer# pip show scapy Name: scapy Version: 2.4.3 Summary: Scapy: interactive packet manipulation tool Home-page: https://scapy.net Author: Philippe BIONDI Author-email: phil(at)secdev.org License: GPLv2 Location: /usr/lib/python2.7/dist-packages Requires: Required-by:
[Python 3
使用的

scapy的版本应该是这个:

root@kali:~/Documents/PycharmWS/packet_sniffer# pip3 show scapy Name: scapy Version: 2.4.3 Summary: Scapy: interactive packet manipulation tool Home-page: https://scapy.net Author: Philippe BIONDI Author-email: phil(at)secdev.org License: GPLv2 Location: /usr/lib/python3/dist-packages Requires: Required-by: 所以基本上版本是相同的:
2.4.3
,并且应该以相同的方式工作(基于Python版本,它只是从不同的目录中获取的。)>

此功能打印包内容时发生奇怪的行为:

def process_sniffed_packet(packet): #print(packet) # Check if our packet has HTTP layer. If our packet has the HTTP layer and it is HTTPRequest. # In this way I am excluding some garbage information in which I am not interested into. if packet.haslayer(http.HTTPRequest): print(packet) print("-------------------------------------") #print(packet.decode("utf-8")) print(type(packet))

这里发生了一件奇怪的事情:

使用

Python 2.7.17]执行脚本,我获得了预期的输出:

root@kali:~/Documents/PycharmWS/packet_sniffer# python packet_sniffer.py jA">�P▒���NPOST / HTTP/1.1� Host: ocsp.int-x3.letsencrypt.org User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/ocsp-request Content-Length: 85 Connection: keep-alive 0S0Q0O0M0K0 +▒~�j�r����� dl�-`]�Jjc}ݺ��9��Ee�������� *y��8:�3zyJ�

使用
Python 3.7.7]解释脚本时,我得到了这个奇怪的编码输出:

root@kali:~/Documents/PycharmWS/packet_sniffer# python3 packet_sniffer.py b'\x00PV\xfd\xa9B\x00PV)\x97\xc7\x08\x00E\x00\x01\xa7\xe8R@\x00@\x06\x9fI\xc0\xa8\xdf\x85\x97\x1dzi\xbaL\x00P\xc3\rj\x11A">\xd1P\x18\xfa\xf0\xb3N\x00\x00POST / HTTP/1.1\r\nHost: ocsp.int-x3.letsencrypt.org\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\r\nAccept: */*\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nContent-Type: application/ocsp-request\r\nContent-Length: 85\r\nConnection: keep-alive\r\n\r\n0S0Q0O0M0K0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14~\xe6j\xe7r\x9a\xb3\xfc\xf8\xa2 dl\x16\xa1-`q\x08]\x04\x14\xa8Jjc\x04}\xdd\xba\xe6\xd19\xb7\xa6Ee\xef\xf3\xa8\xec\xa1\x02\x12\x03\x16\xe6\x87\xfc *y\xc1\xe48:\xdf3zyJ\xa4'

注:最初我怀疑这是字节数组的输出(因为它以** b开头),但不是,我使用:
打印了

packet

变量的类型。print(type(packet)) 并且对象类型是:
<class 'scapy.layers.l2.Ether'>

所以我怀疑这个

scapy.layers.l2.Ether包含一个

bytearray

对象,该对象以这种方式或类似方式打印。无论如何,这应该是pip安装它的文件夹检索到的scapy.layers.l2.Ether代码:

class Ether(Packet): name = "Ethernet" fields_desc = [DestMACField("dst"), SourceMACField("src"), XShortEnumField("type", 0x9000, ETHER_TYPES)] __slots__ = ["_defrag_pos"] def hashret(self): return struct.pack("H", self.type) + self.payload.hashret() def answers(self, other): if isinstance(other, Ether): if self.type == other.type: return self.payload.answers(other.payload) return 0 def mysummary(self): return self.sprintf("%src% > %dst% (%type%)") @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): if _pkt and len(_pkt) >= 14: if struct.unpack("!H", _pkt[12:14])[0] <= 1500: return Dot3 return cls

为什么当我使用
Python 2]打印此对象时,我获得了预期的输出,但使用了

Python 3

打印了该对象,却得到了这个奇怪的“加密”输出?我想念什么?有没有一种方法可以使用Python 3正确打印此输出?我知道我可以使用:
packet.show() 代替
print(packet)

但是我必须使用此

print(packet)
,因为我正在学习使用此特定输出来解析它的教程

我是使用Python的绝对初学者,如果我使用Python 3而不是Python 2执行它,我会在程序中发现以下奇怪的行为。我将尝试解释这种情况……

< [

您可以做
print(bytes(packet).decode(errors="backslashreplace"))
尽管Python3有充分的理由使用字节
python python-3.x python-2.7 scapy
1个回答
0
投票
尽管Python3有充分的理由使用字节
© www.soinside.com 2019 - 2024. All rights reserved.