Почему при печати объекта scapy.layers.l2.Ether с использованием Python 2 я получаю ожидаемый результат, а при печати с использованием Python 3 получаю этот странный вывод? - PullRequest
0 голосов
/ 29 марта 2020

Я абсолютный новичок с Python, и я нахожу следующее странное поведение в моей программе, если я выполняю ее, используя Python 3 вместо использования Python 2 .

Я попытаюсь объяснить ситуацию более подробно.

У меня на компьютере установлены следующие 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")

Этот скрипт реализует простой анализатор трафика c по протоколу HTTP.

Версия scapy , используемая Python 2 должен быть таким:

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: 

Версия scapy , используемая Python 3 , должна быть такой:

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).

странное поведение случается, когда это весело ction напечатать содержимое пакета:

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�

Во время exjectugint сценария с 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 , который печатается таким образом или что-то в этом роде вот так.

В любом случае, это должен быть код scapy.layers.l2.Ether , извлеченный из папки, в которую его установил pip:

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 Я получаю этот st диапазон «зашифрованного» выхода? Что мне не хватает? Есть ли способ правильно распечатать этот вывод, используя Python 3? Я знаю, что могу использовать:

packet.show()

вместо

print(packet)

, но я должен использовать этот print (package) , потому что я следую руководству, которое использует этот специфицированный c вывод для анализа

1 Ответ

1 голос
/ 29 марта 2020

Вы можете сделать

print(bytes(packet).decode(errors="backslashreplace"))

Хотя Python3 использует байты по уважительной причине

...