使用scapy嗅探和解码直径协议
我正在尝试使用scapy和Python来捕获Diameter消息,并解析Diameter部分,以便从Raw.load中提取AVP(属性值对)。在经历了一些失败后,我回到了一个基本的Python/scapy脚本,如下所示:
from scapy.all import *
def pkt_diam(pkt):
raw = pkt.getlayer(Raw).load
print raw
# pkt.show()
sniff(iface="eth0", filter="port 3868", store=0, prn=pkt_diam)
通过打印raw.load,我得到了几个AVP,但内容非常难以阅读。如果我使用
pkt.show()
我会收到整个数据包,包括以太网、IP、TCP和Raw部分,但Raw.load几乎无法使用。
###[ Raw ]###
load = '\x01\x00\x00\xec@\x00\x01/\x01\x00\x00\x00\x07K\x12\xca\x07K\x12\xca\x00\x00\x01\x07@\x00\x00 00000001;000001;61de2650\x00\x00\x01\x04@\x00\x00 \x00\x00\x01\n@\x00\x00\x0c\x00\x00(\xaf\x00\x00\x01\x02@\x00\x00\x0c\x01\x00\x00\x00\x00\x00\x01\x15@\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x01\x08@\x00\x00\x1dtest.a-server.org\x00\x00\x00\x00\x00\x01(@\x00\x00\x14a-server.org\x00\x00\x01)@\x00\x00 \x00\x00\x01\n@\x00\x00\x0c\x00\x00(\xaf\x00\x00\x01*@\x00\x00\x0c\x00\x00\x13\x89\x00\x00\x02t\x80\x00\x008\x00\x00(\xaf\x00\x00\x01\n@\x00\x00\x0c\x00\x00(\xaf\x00\x00\x02u\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x01\x00\x00\x02v\x80\x00\x00\x10\x00\x00(\xaf\x00\x00\x00\x05'
我需要一些帮助来解析和解码Diameter的Raw.load消息。提前谢谢你们!
3 个回答
scapy非常好用。
from scapy.all import *
packets = rdpcap('/path/to/rx.pcap')
def generatePacket():
'''
Generate a packet.
'''
IP()/TCP()/DiamG()
def dissectPacket():
'''
dissect a packet.
'''
packet[0][DiamG]
上面的内容展示了这个想法。你可以用 print(repr(packet[0][DiamG]))
来查看结果。当然,为了确认这个数据包是一个Diameter数据包,你可能想先检查一下:
x = packet[0]
while x.payload:
x = x.payload
if x.name == 'Diameter' # it has diameter message.
# dissect it like above.
如果你想知道如何组装并发送一个Diameter数据包,可以查看这个链接:构建Diameter消息
在当前的Scapy拉取请求中,编号为#109的请求增加了对Diameter层的支持(包括解析和生成)。你可以在这个链接找到相关内容:https://bitbucket.org/secdev/scapy/pull-requests/
你需要下载最新的Scapy源代码和一个名为diameter.py的文件,这个文件需要放在'contribution'目录下(不过请注意,这个文件在当前的2.3.1版本的Scapy中可能无法完全正常工作)。
最好的办法是自己定义Diameter头部,可以参考我刚给你的链接,这里有Scapy文档的一个部分,详细介绍了如何一步一步地构建你自己的协议类型(头部)。
一旦你正确地定义了Diameter()头部,解析Diameter数据包就会变得非常简单。
关于Diameter协议的维基百科页面似乎是一个很好的参考,特别是关于Diameter数据包头部的内容。