
小伙伴们大家好,祝大家元旦快乐。^o^
2020年第一天,斗笠菌将以这篇文章为引子,出一个关于Wireshark的系列,分享使用Wireshark分析网络数据包的一些技巧和案例。这个系列脱离了之前科普的范畴,所以可能需要一些网络和协议方面的知识储备。关于这个系列,斗笠菌是这么规划的:
一. Wireshark
二. Tshark及其他附属工具
三. 深入分析HTTP协议
四. 深入分析TCP协议
第一篇主要关注于Wireshark工具本身,分享一些非常好用的技巧。
1.
初探Wireshark
用Wireshark打开一个网络数据包文件,我们可以看到从上到下,有三个显示部分,依次为:
第一部分为数据包的列表,每一行都是一个数据包,列则是这个包的一些关键信息,比如时间,源IP,目的IP,协议类型等等。
第二部分是当前选中数据包的细节信息,Wireshark已经按照TCP/IP协议栈的分层模型显示出来,可以展开来看到MAC,IP,TCP等协议头部的细节。
第三部分有左右两小块儿,左边是当前选中数据包的HEX数据,也就是以16进制的形式展现这个包的每一个Byte,右边则是每一个字节的ASCII码字符,无法用ASCII码表示的以点来代替。

菜单栏各个按钮小伙伴们可以多点点,比如:
调整时间显示格式:
View > Time Display Format

查看文件基本信息:
Statistics > Capture File Properties

2.
灵活使用过滤器
相信所有第一次用Wireshark看包的同学一定都懵了:抓到了这么多数据包,该怎么定位到我想看的那个呢?
这个时候就须要使用到过滤器了。过滤器就是在菜单栏和数据包列表中间的那个框,我们可以使用它来过滤出我们想看的内容:

比如我们只想看两个特定IP地址X和Y之间的通讯:
ip.addr==x.x.x.x and ip.addr==y.y.y.y
看看效果:

ip.addr不关心这个IP出现在源还是目的,如果你需要按照源或目的来过滤,那么得使用: ip.src和 ip.dst。
当然,如果你想过滤某一个网段,依旧可行:
ip.addr==x.x.x.x/nn
其中,x.x.x.x不是IP地址,而是网络号,nn是掩码长度。
斗笠菌给大家总结一些常用的过滤器:
eth.addr==aa:aa:aa:aa:aa:aa
按照MAC地址过滤。
tcp.port==nnnn
按照TCP端口号过滤。
tcp.analysis.retransmission
过滤出TCP的重传包。
http
过滤出所有的http协议相关报文。
http contains "keyword"
在http的包中过滤"keyword"关键字。
http matches "REGEX"
使用正则表达式过滤
你也可以组合使用不同的过滤器,比如过滤:
X主机和Y主机之间的HTTP报文,HTTP要包含"keyword" 关键字:
ip.addr==x.x.x.x and ip.addr==y.y.y.y and http contains "keyword"
须要注意的是,如果逻辑判断中,同时包含“or”和“and” 那么最好加上括号,比如:
(ip.addr==x.x.x.x and ip.addr==y.y.y.y) or (ip.addr==a.a.a.a and ip.addr==b.b.b.b)
如果你想过滤一个非常细节的信息,比如IP ID,但是又不知道对应的过滤语法,那么一个技巧就是把鼠标放在 IP ID对应的栏位上,右击,选择:
Copy > As Filter

再去过滤栏粘贴就可以了。结果是:
ip.id==0x
灵活使用过滤器,能让我们的工作效率事半功倍,这部分需要时间积累,小伙伴们加油。
3.
自定义列
在分析不同的问题的时候,我们常常须要关注不同的细节字段。比如,有时候须要精确到每一个包的TCP序列号和确认号,有时要看IP ID,有时得看每个HTTP Request的HOST头信息。如果我们点击一个个包来查看这些信息,工作量就大了。那如果我们单独拉出一列来显示这些数据呢?
操作方法是:
右击你想要单独拉出一列的字段,点击:
Apply as Column

然后你就会发现,这一列就已经被单独拉出来了。虽然部分信息Info这一列也有,但是明显单独显示会清晰很多:

案例分享
假如: B是一个HTTP服务器,客户端A给B发了N个HTTP请求,但是有部分请求没有收到回应。现在我们有客户端A上的抓包。需要用Wireshark把没有收到返回的这些HTTP Request找出来。怎么办呢?
我们来分析一下:
这些请求的特征是,在Wireshark中,只看到了HTTP Request,而没有Response。
我们可以用http过滤器来过滤出包中的HTTP Request和Response,然后一个个去找哪些没有Response。但是如果有10000个请求,那就跪了,Orz。
能不能有一个标记位应用到列,然后用这个标记位的值来区分有返回的Request和没有返回的Request呢?
看一个HTTP Request的细节,我们发现Wireshark十分智能地识别出了,与这个Request相对应的Response的位置:

那么如果我们把这个字段应用为一个列呢?
过滤器:
ip.addr==a.a.a.a and ip.addr==b.b.b.b and http.request
再把刚刚这个字段应用到列:

那些Response in frame为空的地方,就是没有返回的HTTP Request。怎么样,神奇不? O(∩_∩)O
那么,如何取消显示一个列呢?
很简单,只需要右击列首,你就可以显示你想要的列了。

使用自定义列的方法,可以让很多看似不可能实现的需求轻松搞定。
4.
显示所有会话
下面介绍一个斗笠菌最喜欢的一个工具:
Statistics > Conversations
可以显示当前抓包文件中的所有会话信息:


上面这张图有点小,依稀可以看到它列出了所有我们关注的TCP会话的细节,包括,开始结束时间,A=>B和B=>A的数据传输量。勾选下面的 "Limit to display filter" 还可以按照过滤器显示。
这个小工具可以让我们宏观总览两个HOST之间的所有通讯过程,十分方便。什么? 你要我举个栗子? 没问题!
案例分享
假设B是一个HTTPS服务器,客户端A访问B下载了一个大文件,但是速度却忽快忽慢,怀疑是TCP层面出了问题。我们在客户端抓了包,想找到这个下载的TCP连接,可是问题来了,HTTPS的包是加密的,而A访问B可能会建立非常多个TCP连接,那么我们怎么找到这个下载大文件的TCP连接呢?
分析一下:
客户端在下载一个大文件,那么一定会有一个TCP连接传递的数据量比其他连接多得多。正常承载Web显示的文件一般都在KB级别,到达MB的很少,那么我们就可以查看TCP会话找到那个数据量最大的连接:

把想要看的会话过滤出来,是不是一眼就找到了它? 如果没有看到,我们还可以单击列首来排序。
查看所有会话可以让我们从宏观角度了解通讯全过程。吐血推荐。
5.
TCP相关工具
上一篇中,斗笠菌曾经说过,最难排查的问题是“访问慢”的问题,而慢的问题90%都可以通过分析TCP的会话得到线索。这个部分Wireshark也给我们提供了非常棒的图形分析工具:
Statistics > TCP Steam Graphs > Time Sequence (tcptrace)


这张图有些难读,涉及到TCP流控的细节,斗笠菌会在本系列最后一篇,深入分析TCP中,详细解读这张图。感兴趣的小伙伴可以先研究一下。
除此之外,在 Statistics > TCP Steam Graphs 下面,还有很多其他TCP数据的图表。同样,会在最后一篇来给大家分享。
好啦,今天的分享就到这里啦。希望能给大家带来帮助,下期我将着重介绍tshark和一些其他常用的附属工具。
我是斗笠菌,一个爱装程序猿的攻城狮。下期再见~
斗笠记,在IT的太空中呼吸