有一个pcap十六进制数据包,格式如下:
0000 D4 C3 B2 A1 02 00 04 00 00 00 00 00 00 00 00 00 ................
0010 FF FF 00 00 01 00 00 00 5F D0 4C 59 57 D6 0E 00 ........_.LYW...
0020 84 00 00 00 84 00 00 00 00 00 C2 85 C1 03 00 00 ................
0030 00 00 00 02 81 00 00 0A 08 00 45 00 00 6E E4 C4 ..........E..n..
0040 00 00 FF 06 C7 AF 01 02 03 04 0A 01 01 0F 00 10 ................
0050 00 0A 00 01 E2 40 00 03 94 47 50 10 10 00 D2 F8 .....@...GP.....
0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090 00 00 00 00 3B C5 9A 8F 38 A4 2B 76 7D 39 7A 68 ....;...8.+v}9zh
00a0 8A 59 F6 A4 CC 32 C7 97 B1 86 F6 50 .Y...2.....P
从0x0025开始的字节00 00 C2 85 C1 03
是我的真实数据包,pcap数据包有一个0x25 = 37字节的标头,我想知道如何在python中的scapy
中解码这个数据包。在以下代码中直接解码它并不起作用:
load_packet = Ether(raw_packet)
print load_packet.src, load_packet.dst
print load_packet.getlayer(IP).src, load_packet.getlayer(IP).dst
print load_packet.getlayer(TCP).sport, load_packet.getlayer().dport
其中raw_packet
是上面的数据包字符串。
答案 0 :(得分:0)
这段代码有点难看(说实话很多),但它有效。
只需将hexdump放在名为stack_overflow
的文件中,然后运行下面的脚本
我已经使用python3.5测试了它,
from scapy.all import *
import sys
def fix_packet(in_file, out_file, offset_to_start):
'''
Create a new hexdump text file without the bytes that need to be skipped
in_file: hexdump file to read from
out_file: hexdump file to write to
offset_to_start: how many bytes (in decimal) to skip until the strat of the actual packet
'''
hex_data_to_store = []
ascii_data_to_store = []
for line in open(in_file, 'r').readlines():
ascii_data = line.strip().split(' ')[len(line.split(' ')) - 1]
hex_data = line.strip().split(' ')[1].split(' ')[0].replace(' ', '')
if not offset_to_start:
hex_data_to_store.append(hex_data)
ascii_data_to_store.append(ascii_data)
else:
if offset_to_start - len(ascii_data) >= 0:
offset_to_start -= len(ascii_data)
else:
hex_data_to_store.append(hex_data[32 - ((len(ascii_data) - offset_to_start) * 2)::])
ascii_data_to_store.append(ascii_data[16 - (len(ascii_data) - offset_to_start)::])
offset_to_start = 0
hex_data_to_store = ''.join(hex_data_to_store)
ascii_data_to_store = ''.join(ascii_data_to_store)
with open(out_file, 'w') as f:
index = 0
while True:
if len(ascii_data_to_store) >= 16:
f.write('{:04x} {} {}\n'.format(index, ' '.join('{}{}'.format(a,b) for a,b in zip(hex_data_to_store[:32:2],
hex_data_to_store[1:32:2])),
ascii_data_to_store[:16]))
hex_data_to_store = hex_data_to_store[32::]
ascii_data_to_store = ascii_data_to_store[16::]
else:
f.write('{:04x} {} {}{}\n'.format(index,
' '.join('{}{}'.format(a,b) for a,b in zip(hex_data_to_store[::2], hex_data_to_store[1::2])),
' '*(16 - len(ascii_data_to_store)), ascii_data_to_store[:]))
break
index += 16
def write_data(data):
'''
This is a trick because import_hexcap reads the hexdump from the stding
'''
with open('new_file', 'w') as f:
f.write(data)
f.write(chr(4))
def read_hex():
old_stdin = sys.stdin
sys.stdin = open('new_file', 'r')
pkt=Ether(import_hexcap())
sys.stdin = old_stdin
return pkt
fix_packet(in_file='stack_overflow', out_file='new_hex', offset_to_start=40)
hex_str = [x.strip() for x in open('new_hex', 'r').readlines()]
write_data('\n'.join(hex_str))
load_packet=read_hex()
print(load_packet.src, load_packet.dst)
print(load_packet.getlayer(IP).src, load_packet.getlayer(IP).dst)
print(load_packet.getlayer(TCP).sport, load_packet.getlayer(TCP).dport)
我得到了以下输出:
>>> print(load_packet.src, load_packet.dst)
00:00:00:00:00:02 00:00:c2:85:c1:03
>>> print(load_packet.getlayer(IP).src, load_packet.getlayer(IP).dst)
1.2.3.4 10.1.1.15
>>> print(load_packet.getlayer(TCP).sport, load_packet.getlayer(TCP).dport)
16 10