Scapy конвертирует пакет в строку и обратно не работает - PullRequest
0 голосов
/ 10 февраля 2019

Я создал собственный пакет scapy.Я хочу преобразовать их в строку и обратно (для имитации получения пакета), и это не работает.

Вот мой код:

main.py:

#!/usr/bin/env python3
import packet

orig_packet = packet.ENIP_TCP() / packet.ENIP_RegisterSession()
orig_packet.show()
str_packet = str(orig_packet[0])
print(str_packet)
dest_packet = packet.ENIP_TCP(str_packet)
dest_packet.show()
reg_session_reply = packet.ENIP_RegisterSession(dest_packet['Raw'])
reg_session_reply.show()

и packet.py:

#!/usr/bin/env python3
'''
This file was partly made thanks to scapy-cip-enip
You can find the github repository here : https://github.com/scy-phy/scapy-cip-enip
The code was modified to fully complied with the ENIP certification book Edition 1.4 November 2007
'''
import struct
from scapy import all as scapy_all

class ENIP_TCP(scapy_all.Packet):
    """Ethernet/IP packet over TCP"""
    name = "ENIP_TCP"
    fields_desc = [
        scapy_all.LEShortEnumField("command", None, {
            0x0000: "NOP",
            0x0004: "ListServices",
            0x0063: "ListIdentity",
            0x0064: "ListInterfaces",
            0x0065: "RegisterSession",
            0x0066: "UnregisterSession",
            0x006f: "SendRRData",
            0x0070: "SendUnitData",
            0x0072: "IndicateStatus",
            0x0073: "Cancel",
        }),
        scapy_all.LEShortField("length", None),
        scapy_all.LEIntField("session_handle", 0),
        scapy_all.LEIntEnumField("status", 0, {
            0x0000: "success",
            0x0001: "Invalid/Unsupported command",
            0x0002: "Insufficient memory resources",
            0x0003: "Incorrect data",
            0x0064: "Invalid session handle",
            0x0065: "Invalid message length",
            0x0069: "Unsupportes encapsulation protocol revision",
        }),
        scapy_all.LELongField("sender_context", 0x0000000000000042),
        scapy_all.LEIntField("options", 0),
    ]

    def extract_padding(self, p):
        return p[:self.length], p[self.length:]

    def post_build(self, p, pay):
        if self.length is None and pay:
            l = len(pay)
            p = p[:2] + struct.pack("<H", l) + p[4:]
        return p + pay

scapy_all.bind_layers(scapy_all.TCP, ENIP_TCP, dport=44818)
scapy_all.bind_layers(scapy_all.TCP, ENIP_TCP, sport=44818)

class ENIP_RegisterSession(scapy_all.Packet):
    name = "ENIP_RegisterSession"
    fields_desc = [
        scapy_all.LEShortField("protocol_version", 1),
        scapy_all.LEShortField("options_flags", 0),
    ]

scapy_all.bind_layers(ENIP_TCP, ENIP_RegisterSession, command=0x0065)

При печати оригинального пакета или пакета str все выглядит нормально, но при отображении пакета dest ничего не соответствует исходному, и я понятия не имею, почему.

РЕДАКТИРОВАТЬ: После дополнительных исследований я обнаружил, что это может быть проблема, связанная с python3.Я думал, что str_packet был в порядке, потому что он отображался как

b'e \ 0x00 \ 0x04 ... '

Но если я закодирую эту строку, результат будет

b "b'e \ x00 \ x04 \ ... '"

Моя проблема сейчас в том, что я понятия не имею, как удалить b' вначало и 'в конце кроме обрезки строки (что некрасиво).Как я могу это сделать?

РЕДАКТИРОВАТЬ: Я нашел решение, если вместо этого:

str_packet = str (orig_packet [0])

Я делаю

str_packet = bytes (orig_packet [0])

Все отлично работает

...