1.问题
python的scapy
库,是构造TCP/IP
报文的利器,并且支持asn.1
,搞过电路交换协议的人一定会明白基于asn.1
协议的描述复杂度。
使用中遇到的一个比较麻烦的问题,scapy
抓到的Packet
如何在网络中传输,如何在使用端还原到Packet
类型。
2.方案
2.1.Packet
转换为str
Packet
转换为str
很简单,直接上代码:
from scapy.all import *
pkts = sniff('eth1', count=1, timeout=5)
pkts[0].show()
pkt_str = str(raw(pkts[0]))
print(pkt_str)
2.2.str
转换为Packet
str
转换为Packet
看上去不那么容易,遇到过两个问题:
- 还原到
Packet
类型,需要bytes
,str
转换为bytes
一直没有试成功; - 还原到
Packet
类型,调用show
方法,没有解析出席完整的报文结构;
对于问题1的方法:
from scapy.all import *
pkts = sniff('eth1', count=1, timeout=5)
pkts[0].show()
pkt_str = str(raw(pkts[0]))
print(pkt_str)
pkt_bytes = eval(pkt_str)
print(pkt_bytes)
利用eval
方法,str
转换到bytes
很容易,不需要对str的编码格式设置,比较方便。
对于问题2的方法:
from scapy.all import *
pkts = sniff('eth1', count=1, timeout=5)
pkts[0].show()
pkt_str = str(raw(pkts[0]))
print(pkt_str)
pkt_bytes = eval(pkt_str)
pkt_old = Ether(pkt_bytes)
pkt_old.show()
scapy
解析报文的时候,需要指定第一层什么时候结构,不然无法进行完整的解析,不明白sniff
的原理,如果知道报文是以太网结构,直接使用类型Ether
构造报文Packet
,再调用show
方法就能完整的解析了。
解决了上述两个问题,就可以方便在网络中传输scapy
的Packet
结构。
3.讨论
既然使用scapy
是网络方面的库,系统往往不是单一进程就能完成的,会涉及到网络传输,Packet
与str
相互转换的问题解决了,就离正式的方案不远了。本文讨论的方法,网上还是比较难找到一个完整的方法,所以贴上来供大家学习使用。
上述的方法,还有一个问题使用sniff
抓到的包,如何确定首层是什么报文呢?这里再附送一个方法,把Packet
转换成json
格式,这样就容易判断了,代码如下:
def packet2json(pkt: Packet):
js = dict()
for key in pkt.fields.keys():
js[key] = str(pkt.fields[key])
if isinstance(pkt.payload, NoPayload):
return js
js[pkt.payload.name] = packet2json(pkt.payload)
return js
enjoy!!!
网友评论