为什么使用 Python 打印 scapy.layers.l2.Ether 对象 2 我在使用 Python 打印它时获得了预期的结果 3 我得到了这个奇怪的输出?
Why printing a scapy.layers.l2.Ether object using Python 2 I obtain the expected result while printing it using Python 3 I obtain this strange output?
我是 Python 的绝对初学者,如果我使用 [=116 执行它,我发现我的程序中有以下奇怪的行为=] 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 协议实现了一个简单的流量嗅探器。
Python2使用的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:
Python3使用的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开头但不是,我打印了[=的类型63=]数据包 变量使用:
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 我得到了这个奇怪的 "ecrypted" 输出?我错过了什么?有一种方法可以使用 Python 3 正确打印此输出吗?
我知道我可以使用:
packet.show()
改为
print(packet)
但我必须使用此 print(packet) 因为我正在学习使用此特定输出来解析它的教程
你可以
print(bytes(packet).decode(errors="backslashreplace"))
虽然 Python3 使用字节是有充分理由的
我是 Python 的绝对初学者,如果我使用 [=116 执行它,我发现我的程序中有以下奇怪的行为=] 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 协议实现了一个简单的流量嗅探器。
Python2使用的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:
Python3使用的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开头但不是,我打印了[=的类型63=]数据包 变量使用:
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 我得到了这个奇怪的 "ecrypted" 输出?我错过了什么?有一种方法可以使用 Python 3 正确打印此输出吗? 我知道我可以使用:
packet.show()
改为
print(packet)
但我必须使用此 print(packet) 因为我正在学习使用此特定输出来解析它的教程
你可以
print(bytes(packet).decode(errors="backslashreplace"))
虽然 Python3 使用字节是有充分理由的