PyShark入门(4):packet对象
本系列文章译自thePacketGeek的系列文章。原创翻译,转载请注明出处。
目前在这一系列文章中我们已经了解了如何捕获数据包和使用 capture 对象,我们终于到了有趣的部分,开始对数据包进行操作了!
当我们捕获了数据包后,它们以 packet 对象列表的形式存储在 capture 对象中。这些 packet 对象的方法和属性使我们能够访问数据包头以及包的负载信息。在之前的文章中提到过,我们可以使用 only_summaries 参数来控制每个数据包保存的信息量。
数据包摘要属性
在捕获时将 only_summaries 设置为 True 会使得不管捕获的数据包的内容是何种协议, packet 对象都具有固定的属性集。其中最有用的属性值有:
1 | 'test.pcap', only_summaries=True) cap = pyshark.FileCapture( |
- delta : 当前数据包和上一个数据包捕获时间的差值。
- destination : IP层的目标地址。
- info :应用层数据的简短摘要(比如”HTTP GET /resource_folder/page.html”)。
- ip id : IP标识符字段。
- length : 以字节表示的数据包长度。
- no : 数据包在列表中的索引值。
- protocol : 数据包中识别出的最高层级的协议。(译注:HTTP数据包如果是JSON的数据,此处可能是JSON而非HTTP)
- source : IP层的源地址。
- stream : 索引值,标识出该数据包属于哪一个TCP流(仅用于TCP数据包)。
- summary_line : 将所有的摘要属性输出在一个tab分隔的字符串中。
- time : 当前数据包到达时间与第一个数据包的差值。
- window : TCP的窗口大小(仅用于TCP数据包)。
利用这些内容可以做很多事情,打印出数据包摘要只是一个开始!利用这些数据可以做出很棒的可视化图表来展示IP会话、带宽使用、协议以及应用的性能指标(比如TCP数据流中的RTT值)。这都是很有用的分析,还有别的吗?
完整的数据包属性
如果你不仅想从捕获的数据包中获取摘要信息,那么好好看看这部分吧。使用Wireshark和tshark内建的解析器,PyShark可以将数据包的所有细节按层次分解。
比如我们先来深入研究一下DNS数据包,看一下数据包所具有的属性。
1 | 'en0', bpf_filter='udp port 53') cap = pyshark.LiveCapture(interface= |
这其中有一些普通的数据包信息属性,比如length
,frame_info
,以及time
,还有pretty_print()
方法用于以可读性较强的方式显示数据包(类似于Wireshark的详细信息视图)。
如果你仔细看的话能够发现直接制定层次名的属性(eth
和ip
),还有会根据数据包内的协议而变动的属性(transport_layer
和highest_layer
)。
如果你要寻找特定类型的数据流量,这些属性可以使得寻找感兴趣的信息变得很简单。
比如下面的脚本会打印出所有的DNS查询和响应:
1 | import pyshark |
会给出如下的结果:
1 | DNS Request from 10.10.10.40: apple.com |
动态的层引用
使用上面提到的动态变化的层属性(比如transport_layer
和highest_layer
)让我们在分析数据包时更灵活。
如果你对每个数据包都试图访问pkt.dns.qry_resp
属性,那么如果这个数据包不是DNS数据包就会返回AttributeError
异常。传输层也有类似的问题,因为有TCP和UDP两种可能。我们可以使用动态引用的层属性来获取源地址和目的地址,然后使用try/except来处理既不是TCP也不是UDP数据包的情况。
1 | import pyshark |
该脚本会输出:
1 | UDP 10.10.10.12:51554 --> 239.255.255.250:1900 |
无限的可能
从这几个简单的例子当中我们可以看出,PyShark使我们能够轻松的访问所有的数据包细节。
在分类和处理多种不同协议的时候,可以使用条件语句来创造动态的逻辑,你也可以寻找具有特定属性的数据包来筛选特定类型的数据流量(当然要注意处理AttributeError)。
希望你喜欢这一系列文章。如果你对PyShark的应用实例感兴趣,你可以看看我的Cloud-Pcap项目