I'm having trouble with decoding data (or maybe encoding on send) from scapy.
I'm attempting to send some UDP HEX data with scapy then decode it back to the original form, but the HEX string received has ASCII characters in it.
from scapy.all import *
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
test_data = ["000ad74340b81e4941002900020202000200"] # This is actually read from a file.
source_ip = "192.168.1.12"
destination_ip = "192.168.1.4"
source_mac = "70:85:c2:f3:18:8e"
destination_mac = "80:ce:62:f2:94:22"
source_port = 5005
destination_port = 5005
tmp = []
byte_str = [(test_data[0][i:i + 2]) for i in range(0, len(test_data[0]), 2)]
for i in range(len(byte_str)):
tmp.append(int(f"0x{byte_str[i]}", 16))
data_to_send = bytearray(tmp)
print("b'" + ''.join(f'\\x{c:02x}' for c in data_to_send) + "'")
pkt = Ether(dst=destination_mac, src=source_mac)/\
IP(dst=destination_ip, src=source_ip, flags=2)/\
UDP(dport=destination_port, sport=source_port)/data_to_send
del pkt[IP].chksum
del pkt[UDP].chksum
pkt.show2()
sendp(pkt)
Whats being sent
###[ Ethernet ]###
dst = 80:ce:62:f2:94:22
src = 70:85:c2:f3:18:8e
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 46
id = 1
flags = DF
frag = 0
ttl = 64
proto = udp
chksum = 0xb75d
src = 192.168.1.12
dst = 192.168.1.4
\options \
###[ UDP ]###
sport = 5005
dport = 5005
len = 26
chksum = 0xaeed
###[ Raw ]###
load = '\x00\n\\xd7C@\\xb8\x1eIA\x00)\x00\x02\x02\x02\x00\x02\x00'
.
Sent 1 packets.
Whats received is \x00\n\\xd7C@\\xb8\x1eIA\x00)\x00\x02\x02\x02\x00\x02\x00
, and i'm trying to figure out how i get back to 000ad74340b81e4941002900020202000200
or something like this \x00\x0a\xd7\x43\x40\xb8\x1e\x49\x41\x00\x29\x00\x02\x02\x02\x00\x02\x00
.
When i convert 000ad74340b81e4941002900020202000200
to a list of hex values ['00', '0a', 'd7', '43', '40', 'b8', '1e', '49', '41', '00', '29', '00', '02', '02', '02', '00', '02', '00']
, then convert them to a list ints [0, 10, 215, 67, 64, 184, 30, 73, 65, 0, 41, 0, 2, 2, 2, 0, 2, 0]
to create a bytearray bytearray(b'\x00\n\xd7C@\xb8\x1eIA\x00)\x00\x02\x02\x02\x00\x02\x00')
, i can then convert that back to b'\x00\x0a\xd7\x43\x40\xb8\x1e\x49\x41\x00\x29\x00\x02\x02\x02\x00\x02\x00'
.
But when i read the payload info from the scapy UDP packet i get the following string "b'\\x00\\n\\xd7C@\\xb8\\x1eIA\\x00)\\x00\\x02\\x02\\x02\\x00\\x02\\x00'"
, which when i convert it to a bytestring, it still has the \\
and i can't convert ot back to the original hex data above.
How can i convert str "\\x00\\n\\xd7C@\\xb8\\x1eIA\\x00)\\x00\\x02\\x02\\x02\\x00\\x02\\x00"
to b'\x00\n\xd7C@\xb8\x1eIA\x00)\x00\x02\x02\x02\x00\x02\x00'
with a single \
so i can then use print("b'" + ''.join(f'\\x{c:02x}' for c in bytearray(RECEIVED_DATA) + "'")
to get the original hex data back?
Use bytes.hex()
and str.fromhex()
to convert between representations:
>>> s = "000ad74340b81e4941002900020202000200" # ASCII string of hex digits
>>> s
'000ad74340b81e4941002900020202000200'
>>> b = bytes.fromhex(s)
>>> b # Default *display* representation of bytes.
b'\x00\n\xd7C@\xb8\x1eIA\x00)\x00\x02\x02\x02\x00\x02\x00'
>>> list(b) # decimal values of the bytes are correct
[0, 10, 215, 67, 64, 184, 30, 73, 65, 0, 41, 0, 2, 2, 2, 0, 2, 0]
>>> # Display a custom way (no ASCII). This is *just* for display.
>>> print("b'" + ''.join(f'\\x{n:02x}' for n in b) + "'")
b'\x00\x0a\xd7\x43\x40\xb8\x1e\x49\x41\x00\x29\x00\x02\x02\x02\x00\x02\x00'
>>> b.hex() # display bytes as hexadecimal string again
'000ad74340b81e4941002900020202000200'
>>> b.hex(sep=' ') # with a separator if desired.
'00 0a d7 43 40 b8 1e 49 41 00 29 00 02 02 02 00 02 00'
Note that the type of a bytes
object element is int
so you can iterate over them and perform calculations if needed:
>>> type(b[0])
<class 'int'>
>>> for n in b:
... print(f'{n:3d} {n:02X}')
...
0 00
10 0A
215 D7
67 43
64 40
184 B8
30 1E
73 49
65 41
0 00
41 29
0 00
2 02
2 02
2 02
0 00
2 02
0 00