Я создал собственный пакет 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])
Все отлично работает