大学上计算机网络的时候就学习了TCP的三次握手协议,当时我学的时候就觉得这些东西好虚啊,看不见摸不着,学的费心费力,结果却差强人意。最近因为要做TCP/IP的课设,老师要求要用wireshark,然后就接触到了这款开源软件Wireshark。通过了解知道这是一款非常流行的网络封包分析软件,功能十分强大,可以截取各种网络封包,显示网络封包的详细信息。有了wireshark就能截获这些网络数据包,可以清晰的看到数据包中的每一个字段。更能加深我们对网络协议的理解。(所以在这插一句话哦: 理论指导实践,实践发展理论)在过去,网络封包分析软件是非常昂贵的,或是专门属于盈利用的软件。wireshark的出现改变了这一切。在GNUGPL通用许可证的保障范围底下,使用者可以以免费的途径取得软件与其源代码,并拥有针对其源代码修改及客制化的权利。
Ethereal(wireshark的前身)是全世界最广泛的网络封包分析软件之一。为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包。wireshark能获取HTTP,也能获取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的内容.
总结,如果是处理HTTP,HTTPS 还是用Fiddler, 其他协议比如TCP,UDP 就用wireshark.
简单介绍一下:Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件)。
Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还提供了一个用户友好的格式。它是用C#写出来的,包含一个简单却功能强大的基于JScript .NET 事件脚本子系统,它的灵活性非常棒,可以支持众多的http调试任务,并且能够使用.net框架语言进行扩展。(百度百科,官方文档)
那么我们在Linux系统下一般用什么抓包工具呢?
那就是TCPDUMP啦!
简单介绍一下:TCPDump可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。
Linux作为网络服务器,特别是作为路由器和网关时,数据的采集和分析是不可少的。TcpDump是Linux中强大的网络数据采集分析工具之一。
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。
作为互联网上经典的的系统管理员必备工具,tcpdump以其强大的功能,灵活的截取策略,成为每个高级的系统管理员分析网络,排查问题等所必备的工具之一。(官方文档)
上图,一般用作对手机应用上网时的抓包分析,比如说想分析手机版微信聊天或者打开朋友圈的数据包。
点击不同协议的数据包,数据包分层协议展示的内容就不一样,上图笔者分别选中的是第六个(TLS)和第七个(TCP)数据包。
TLS:它是一个在传输层为数据提供保密和完整性的一个安全协议,说白了就是保障传输层数据包的安全,大家所熟知的HTTPS中的S就是TLS。
再例如:http协议是一个应用协议所以
对IP层数据报进行一一对应:
对TCP数据报进行一一对应
简单介绍一下Wireshark分析数据包时最重要的技巧之一的过滤器。一次性嗅探到的数据包有很多,想要高效地提取出你想要的数据包或者对某个数据包中某个字段值的分析等,必不可少的就是过滤。过滤器分为捕捉过滤器(CaptureFilters)和显示过滤器(DisplayFilters)。
可以把捕获过滤器看作是一级过滤,显示过滤看做二级过滤
也就是说:先规定一下数据报的特征(一级过滤),由于需求过滤完之后还是满足不了要求所以再进行一次过滤(二级过滤),笔者只是打个比方,可能不太严谨。
捕获过滤器表达式作用在wireshark开始捕获数据包之前,只捕获符合条件的数据包,不记录不符合条件的数据包。
捕获过滤器表达式没有像显示过滤器表达式那样明显的规律,但写法不多所以也不难;而且除非全部捕获要占用的磁盘空间实现太大,且你非常明确过滤掉的数据包是你不需要的,不然一般都不用捕获过滤器表达式而用显示过滤器表达式。
如何打开捕获过滤器:
Protocol(协议)
可能的值: ether, fddi, ip, arp, rarp, decnet, tcp and udp等。如果没有特别指明是什么协议,则默认使用所有支持的协议
Direction(方向)
可能的值: src, dst, src and dst, src or dst。如果没有特别指明来源或目的地,则默认使用 “src or dst” 作为关键字
比如:”host 10.2.2.2″与”src or dst host 10.2.2.2″是一样的
Host(s)
可能的值: net, port, host, portrange。如果没有指定此值,则默认使用”host”关键字
比如:"src 10.1.1.1"与”src host 10.1.1.1″相同
Logical Operations(逻辑运算)
可能的值:not, and, or
否(“not”)具有最高的优先级。或(“or”)和与(“and”)具有相同的优先级,运算时从左至右进行。
例如,
“not tcp port 3128 and tcp port 23"与”(not tcp port 3128) and tcp port 23"相同。
"not tcp port 3128 and tcp port 23"与"not (tcp port 3128 and tcp port 23)"不同。
显示目的TCP端口为3128的封包
tcp dst port 3128
显示来源IP地址为10.1.1.1的封包
ip src host 10.1.1.1
显示目的或来源IP地址为10.1.2.3的封包
host 10.1.2.3
显示来源为UDP或TCP,并且端口号在2000至2500范围内的封包
src portrange 2000-2500
显示除了icmp以外的所有封包
not icmp
显示来源IP地址为10.7.2.12,但目的地不是10.200.0.0/16的封包
src host 10.7.2.12 and not dst net 10.200.0.0/16
显示源IP为10.4.1.12或源网络为10.6.0.0/16,目的TCP 端口号在200至10000之间,并且目的位于网络 10.0.0.0/8内所有封包
(src host 10.4.1.12 or scr net 10.6.0.0/16) and tcp dst portrange 200-10000 and dst net 10.0.0.0/8
捕获广播流量
broadcast
显示过滤器表达式作用在在wireshark捕获数据包之后,从已捕获的所有数据包中显示出符合条件的数据包,隐藏不符合条件的数据包。
显示过滤表达示在工具栏下方的“显示过滤器”输入框输入即可生效
Protocol(协议)
位于OSI模型第2至7层的协议,如:IP、TCP、DNS等
String1,String2(可选项)
协议的子类
Logical Operations(逻辑运算符)
逻辑异或是一种排除性的或。当其被用在过滤器的两个条件之间时,只有当且仅当其中的一个条件满足时,这样的结果才会被显示在屏幕上
例如:“tcp.dstport 80 xor tcp.dstport 1025”
只有当目的TCP端口为80或者来源于端口1025(但又不能同时满足这两点)时,这样的数据包才会被显示
显示SNMP或DNS或ICMP封包
snmp || dns || icmp
显示来源或目的IP地址为10.1.1.1的封包
ip.addr == 10.1.1.1
显示来源不为10.1.2.3或目的不为10.4.5.6的包
ip.src != 10.1.2.3 or ip.dst != 10.4.5.6
显示来源或目的TCP端口号为25的封包
tcp.port == 25
显示目的TCP端口号为25的封包
tcp.dstport == 25
显示包含TCP标志的封包
tcp.flags
显示包含TCP SYN标志的封包
tcp.flags.syn == 1
排除arp流量
!arp
文本管理流量(telnet或ftp)
tcp.port == 23 || tcp.port == 21
可以看出这两种过滤器在使用和功能上有着区别:
捕捉过滤器是数据经过的第一层过滤器,它用于控制捕捉数据的数量,以避免产生过大的日志文件。而显示过滤器是在对捕获结果进行筛选时使用,允许我们在日志文件中迅速准确地找到所需要的记录。
捕捉过滤器必须在捕捉数据包之前设置,若是捕捉的数据包不是我们想要的,需要重新设置捕捉过滤器并重新捕捉数据包。显示过滤器的功能比捕捉过滤器更为强大,可以重复设置表达式对捕获的结果重复筛选而不需要重新捕获数据包。
跟踪TCP流
上图中可以看到wireshark截获到了三次握手的三个数据包。第四个包才是HTTP的, 这说明HTTP的确是使用TCP建立连接的。
第一次握手数据包
客户端发送一个TCP,标志位为SYN,序列号为0, 代表客户端请求建立连接。
第二次握手的数据包
服务器发回确认包, 标志位为 SYN,ACK. 将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即0+1=1
第三次握手的数据包
客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1
下图为TCP三次握手的流程图
如下图,第7包数据,本应收到seq number为1366882的TCP包,但却收到了1044834的包,这包数据应该是晚到了,因此wireshark标记为out-of-order。
如果抓包中出现大量的out-of-order包,则说明网络存在较大的TCP乱序或丢包。
这些分片正常应该是连续接收的,即前一个分片指示的next seq number即为下一个收到的分片的seq number。假如收到的下一个分片的seq number与上一个比不连续的话,wireshark就会将该分片标记为TCP Previous segment not captured。如下图,ack number为705的TCP包被分为多个分片发送,其中有一个长度为1408的分片没有被抓到。
需要注意的是,前一个分片丢失,有可能是网络中确实丢失了,或者晚到了,也有可能是wireshark本身并没有抓到。
TCP fast Retransmission
TCP快速重传。
TCP协议设定了快速重传机制以避免过多的慢启动对传输速率的影响。快速重传通过接收到3个或3个以上重复的ack反馈触发。快速重传不需要等待RTO超时。如下图。
325包,客户端向服务端反馈ack=133251,说明下一个期望收到服务端seq=133251的包;
326包,服务端向客户端发送了seq=135771的数据包,与客户端的期望不符,因此客户端在327包重传了ack=133251的包,再次申明期望收到seq=133251的包。Wireshark将重复ack标记为TCP Dup ACK,#后边指明为第几次重传。
328包,服务端向客户端发送了seq=137031的数据包,仍然与客户端期望不符,客户端在329包再次重传ack=133251的包。
330包,服务端收到3次重复ack,触发快速重传,重传了seq=133251的TCP分片。
TCP Dup ACK
重复ack。
当网络中存在乱序或者丢包时,将会导致接收端接收到的seq number不连续。此时接收端会向发送端回复重复ack,ack值为期望收到的下一个seq number。重复ack数大于等于3次将会触发快速重传。如下图,
315包,客户端向服务端发送ack=126951的反馈,期望下一包收到seq=126951的TCP包。但下一包接收到的却是seq=128211的TCP包,由于seq不连续,wireshark将该报标记为TCP Previous segment not captured。
317包,客户端向服务端重复发送ack=126951的包,第一次重发,#后边带1。
318包,客户端收到seq=126951的TCP包。
319包,截止到seq=129471的所有TCP包全部收到,因此客户端回复了ack=129471的反馈。
TCP window update
TCP窗口更新。
当接收方的TCP window发生突变时,接收方通过TCP window update消息告知对方当前的接收窗口大小。如下图,TCP window Update同时携带了反馈ack,ack序列号与前一个反馈ack序列号相同,但这并不是重复ack。
TCP acked unseen segment
反馈ACK指向了一个未知的TCP片段。
这个意思是说ACK反馈的是一个wireshark上不存在的TCP包。很可能是wireshark漏抓了这个包,但却抓到了对端反馈的该报的ack包。如下图,标记为ack unseen segment的包反馈的ack=2721,看着像是反馈的seq=1361的包,但其实这个ack还反馈了seq=1的包,由于seq=1的包没有抓到,因此wireshark将反馈ack标记为ack unseen segment。从下面的图还可知,由于对端已经反馈了ack=2721,说明发端发送的seq=1的包,对端也收到了,只不过wireshark可能漏抓了而已。
TCP ZeroWindow
TCP滑动窗口为0。
当发送端发包速率大于接收端的接收速率时,会造成接收端TCP window越来越小,当接收端在反馈ack时携带的window size=0时,wireshark标记TCP Zero window。此时发送端将暂停发送数据,直到收到接收端window size!=0的标志。
TCP window full
TCP window满。
是指的发送端发送的数据已经达到的接受窗口的上限。发送端暂停发送,等待新的接收窗口的通告。
如下图,客户端向服务端发送的ack反馈,期望下一包收到的seq=288961,但接收窗口仅有960,服务端在收到ack后发送了960字节的数据,TCP window full。注意,len=1004是整个IP包的长度,需要减去IP头44字节,即960字节。
TCP RST
TCP 重置。
是TCP协议结束异常连接的一种方式,通过flog中的reset=1标记。当TCP连接无法通过正常的4次挥手结束时,一方可以通过发送携带reset标志的TCP包结束TCP连接。
如下图,发送方通过2个TCP流发送数据,截图中,接收方首先向发送方反馈了TCP window=0,让发送方暂缓发送数据,之后紧接着发送了TCP RST标记,释放了TCP连接。猜测可能接收方程序突然崩溃了,导致缓存区数据没法清空,之后接收方系统发送了TCP reset释放TCP连接。