Wireshark是什么
Wireshark是使用最广泛的一款「开源抓包软件」,常用来检测网络问题、攻击溯源、或者分析底层通信机制。
它使用WinPCAP作为接口,直接与网卡进行数据报文交换。
Wireshark抓包原理
Wireshark使用的环境大致分为两种,一种是电脑直连互联网的单机环境,另外一种就是应用比较多的互联网环境,也就是连接交换机的情况。
- 单机情况下,Wireshark直接抓取本机网卡的网络流量;
- 交换机情况下,Wireshark通过端口镜像、ARP欺骗等方式获取局域网中的网络流量。
- 端口镜像:利用交换机的接口,将局域网的网络流量转发到指定电脑的网卡上。
- ARP欺骗:交换机根据MAC地址转发数据,伪装其他终端的MAC地址,从而获取局域网的网络流量。
Wireshark快速入门
进入界面(选择网卡)
打开 Wireshark 后,会直接进入「网卡选择界面」,WLAN 是我连接无线的网卡,我们抓一下这个网卡的流量,双击网卡名,自动开始抓包。(另外一种方式,停止抓取后,点击旁边设置按钮)
界面介绍
Wireshark 的主界面包含6个部分:
- 菜单栏:用于调试、配置
- 工具栏:常用功能的快捷方式
- 过滤栏:指定过滤条件,过滤数据包
- 数据包列表:核心区域,每一行就是一个数据包
- 数据包详情:数据包的详细数据
- 数据包字节:数据包对应的字节流,二进制
Packet List Pane(数据包列表)
显示捕获到的数据包,每个数据包包含编号,时间戳,源地址,目标地址,协议,长度,以及数据包信息。
不同协议的数据包使用了不同的颜色区分显示。(可自定义颜色)
Packet Details Pane(数据包详细信息)
在数据包列表中选择指定数据包,在数据包详细信息中会显示数据包的所有详细信息内容。
数据包详细信息面板是最重要的,用来查看协议中的每一个字段。
各行信息分别为:
- Frame: 物理层的数据帧概况
- Ethernet II: 数据链路层以太网帧头部信息
- Internet Protocol Version 4: 互联网层IP包头部信息
- Transmission Control Protocol: 传输层T的数据段头部信息,此处是TCP
- Hypertext Transfer Protocol: 应用层的信息,此处是HTTP协议
TCP包的具体内容
从下图可以看到wireshark捕获到的TCP包中的每个字段。
Wireshark基础使用
调整界面大小
工具栏中的三个「放大镜」图标,可以调整主界面数据的大小。
设置显示列
数据包列表是最常用的模块之一,列表中有一些默认显示的列,我们可以添加、删除、修改显示的列。
1)添加显示列
想要在数据列表中显示某一个字段,可以将这个数据字段添加至显示列中。
左键选中想要添加为列的字段,右键选择「应用为列」。
选中字段,按 Ctrl + Shift + I
,也可以实现同样的效果。
添加为列的字段会在数据列表中显示。
2)隐藏显示列
暂时不想查看的列,可以暂时隐藏起来。
在显示列的任意位置右键,取消列名的「勾选」,即可隐藏显示列。
3)删除显示列
不需要查看的字段,可以从显示列中删除。
右键需要删除的列,点击最下方的「Remove this Column」 。
注意:隐藏字段时,在列名栏的任意位置右键即可;而删除字段时,需要在指定的列名位置右键,以防误删。
设置时间
数据包列表栏的时间这一列,默认显示格式看起来很不方便,我们可以调整时间的显示格式。
点击工具栏的「视图」,选择「时间显示格式」,设置你喜欢的格式。
标记数据包
对于某些比较重要的数据包,可以设置成高亮显示,以达到标记的目的。
选中需要标记的数据包,右键选择最上面的「标记/取消标记」。
导出数据包
演示快速抓包时,我们讲过保存数据包的操作,保存操作默认保存所有已经抓取的数据包。但有时候,我们只需要保存指定的数据包,这时候可以使用导出的功能。
1)导出单个数据包
选中数据包,点击左上角的「文件」,点击「导出特定分组」。
在「导出分组界面」,选择第二个 「Selected packets only」,只保存选中的数据包。
2)导出多个数据包
有时候我们需要导出多个数据包,Wireshark有一个导出标记的数据包的功能,我们将需要导出的数据包都标记起来,就可以同时导出多个数据包。
点击左上角的「文件」,点击「导出特定分组」。
在「导出分组界面」,勾选第三个 「Marked packets only」,只导出标记的数据包。
开启混杂模式
局域网的所有流量都会发送给我们的电脑,默认情况下,我们的电脑只会对自己mac的流量进行解包,而丢弃其他mac的数据包。
开启混杂模式后,我们就可以解析其他mac的数据包,因此,我们使用Wireshark时,通常都会开启混杂模式。
点击菜单栏的「捕获」按钮,点击「选项」。
勾选 在所有接口上使用混杂模式。
过滤器操作
过滤器是Wireshark的核心功能,也是我们平时使用最多的一个功能。
Wireshark提供了两个过滤器:抓包过滤器 和 显示过滤器。两个过滤器的过滤思路不同。
- 抓包过滤器:重点在动作,需要的包我才抓,不需要的我就不抓。
- 显示过滤器:重点在数据的展示,包已经抓了,只是不显示出来。
抓包过滤器
抓包过滤器在抓包前使用,它的过滤有一个基本的语法格式:BPF语法格式。
BPF语法
BPF(全称 Berkeley Packet Filter),中文叫伯克利封包过滤器,它有四个核心元素:类型、方向、协议 和 逻辑运算符。
- 类型Type:主机(
host
)、网段(net
)、端口(port
) - 方向Dir:源地址(
src
)、目标地址(dst
) - 协议Proto:各种网络协议,比如:
tcp、udp、http
- 逻辑运算符:与(
&&
)、或(||
)、非(!
)---(逻辑运算符为and/or/not
)
4个元素可以自由组合,比如:
src host 192.168.31.1 # 抓取源IP为 192.168.31.1 的数据包
tcp || udp # 抓取 TCP 或者 UDP 协议的数据包
tcp.port ==80 # 显示源主机或者目的主机端口为80的数据包列表。
tcp.srcport == 80 # 只显示TCP协议的源主机端口为80的数据包列表。
tcp.dstport == 80 # 只显示TCP协议的目的主机端口为80的数据包列表。
http.request.method=="GET" # 只显示HTTP GET方法的。
使用方式
- 使用抓包过滤器时,需要先停止抓包,设置完过滤规则后,再开始抓包。
- 停止抓包的前提下,点击工具栏的捕获按钮,点击选项。
- 在弹出的捕获选项界面,最下方的输入框中输入过滤语句,点击开始即可抓包。
抓包过滤器的输入框,会自动检测语法,绿色代表语法正确,红色代表语法错误。
显示过滤器
显示过滤器在抓包后或者抓包的过程中使用。
语法结构
显示过滤器的语法包含5个核心元素:IP、端口、协议、比较运算符和逻辑运算符。
- IP地址:
ip.addr
、ip.src
、ip.dst
- 端口:
tcp.port
、tcp.srcport
、tcp.dstport
- 协议:
tcp
、udp
、http
- 比较运算符:
>
<
==
>=
<=
!=
- 逻辑运算符:
and
、or
、not
、xor
(有且仅有一个条件被满足)---也可以使用:与(&&
)、或(||
)、非(!
)
5个核心元素可以自由组合,比如:
ip.addr == 192.168.32.121:显示IP地址为 192.168.32.121 的数据包
tcp.port == 80 :显示端口为 80 的数据包
使用方式
在过滤栏输入过滤语句,修改后立即生效。
过滤栏有自动纠错功能,绿色表示语法正确,红色表示语法错误。
抓包过滤器和显示过滤器的使用选择
在组网不复杂或者流量不大情况下,使用显示器过滤器进行抓包后处理就可以满足我们使用。
按照数据包内容过滤
可以单击选中界面中的码流,在下方进行选中数据。如下
选中Select后在过滤器中显示如下
后面条件表达式就需要自己填写。如上我想过滤出json数据包中包含"name"内容的数据流。包含的关键词是contains 后面跟上内容。
Wireshark抓包分析TCP三次握手
TCP三次握手连接建立过程
- 客户端发送一个
SYN=1
,ACK=0
标志的数据包给服务端,请求进行连接,这是第一次握手; - 服务端收到请求并且允许连接的话,就会发送一个
SYN=1
,ACK=1
标志的数据包给发送端,告诉它,可以通讯了,并且让客户端发送一个确认数据包,这是第二次握手; - 服务端发送一个
SYN=0
,ACK=1
的数据包给客户端端,告诉它连接已被确认,这就是第三次握手。TCP连接建立,开始通讯。
wireshark抓包获取访问指定服务端数据包
- 启动wireshark抓包,打开浏览器输入
www.huawei.com
。 - 使用
ping www.huawei.com
获取IP。
- 输入过滤条件获取待分析数据包列表
ip.addr == 61.54.86.163
图中可以看到wireshark截获到了三次握手的三个数据包。第四个包才是HTTP的, 这说明HTTP的确是使用TCP建立连接的。
第一次握手数据包
客户端发送一个TCP,标志位为SYN,序列号为0, 代表客户端请求建立连接。如下图。
数据包的关键属性如下:
SYN
:标志位,表示请求建立连接Seq = 0
:初始建立连接值为0,数据包的相对序列号从0开始,表示当前还没有发送数据Ack =0
:初始建立连接值为0,已经收到包的数量,表示当前没有接收到数据
第二次握手的数据包
服务器发回确认包, 标志位为 SYN,ACK
将确认序号(Acknowledgement Number)设置为客户的ISN加1,即0+1=1, 如下图
数据包的关键属性如下:
[SYN + ACK]
: 标志位,同意建立连接,并回送SYN+ACKSeq = 0
:初始建立值为0,表示当前还没有发送数据Ack = 1
:表示当前端成功接收的数据位数,虽然客户端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位。(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)
第三次握手的数据包
客户端再次发送确认包(ACK) SYN
标志位为0
,ACK
标志位为1
,并且把服务器发来ACK的序号字段+1
,放在确定字段中发送给对方.并且在数据段放写ISN
的+1
, 如下图:
数据包的关键属性如下:
ACK
:标志位,表示已经收到记录Seq = 1
:表示当前已经发送1个数据Ack = 1
: 表示当前端成功接收的数据位数,虽然服务端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)。
就这样通过了TCP三次握手,建立了连接。开始进行数据交互
下面针对数据交互过程的数据包进行一些说明:
数据包的关键属性说明
Seq
: 1Ack
: 1: 说明现在共收到1字节数据
Seq
: 1Ack
: 951: 说明现在服务端共收到951字节数据
TCP的六种状态:SYN
, FIN
, ACK
, PSH
, RST
, URG
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN(synchronous), FIN(Finish), ACK(Acknowledge ), PSH(Push), RST(Reset), URG(Urgent)。如下
其中,对于我们日常的分析有用的就是前面的五个字段。它们的含义是:SYN表示建立连接,FIN表示关闭连接,ACK表示响应,PSH表示有DATA数据传输,RST表示连接重置。
Wireshark抓包分析TCP四次挥手
四次挥手标志分别为:
[FIN, ACK]
[ACK]
[FIN, ACK]
[ACK]
这里,我们需要注意两点:
(1)客户端与服务器端传输时全双工的,因此断开请求既可以由客户端发起,也可以由服务器端发起。只要找准第一次出现[FIN, ACK]
的位置,就是第一次挥手位置。
(2)为什么我们抓包抓到的不是“四次挥手”,而是“三次挥手”呢?
这里涉及到LInux的TCP时延机制,当被挥手端(这里是12672端口)第一次收到挥手端(这里是443端口)的“FIN”请求时,并不会立即发送ACK,而是会经过一段延迟时间后再发送,但是此时被挥手端也没有数据发送,就会向挥手端发送“FIN"请求,这里就可能造成被挥手端发送的“FIN”与“ACK”一起被挥手端收到,导致出现“第二、三次挥手”合并为一次的现象,也就最终呈现出“三次挥手”的情况。
三次握手:
第一次握手:客户端发送syn包(`seq=x`)到服务器,并进入`SYN_SENT`状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(`ack=x+1`),同时自己也发送一个SYN包(`seq=y`),即`SYN+ACK`包,此时服务器进入`SYN_RECV`状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(`ack=y+1`),此包发送完毕,客户端和服务器进入`ESTABLISHED`状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
四次挥手:
与建立连接的“三次握手”类似,断开一个TCP连接则需要“四次握手”。
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。首先我们需要把浏览器的页面关闭,也就是断开`TCP/IP`连接,之后等待几分钟。会出现下面的画面,方框就是“挥手”过程。
FAQ
使用wireshark出现很多TCP Retransmission(重发)信息
出现TCP Retransmission
多数是因为目标主机的端口没开有开放监听,很少出现是网络不好导致的。
如果在某个时间段(RTT的倍数)内没有确认发送的数据,则将数据重新传输到远程主机。重传超时从RTT开始,并随着每次重传而增加一倍。重传超时总是受限于CFGZ-MNRTO
和CFGYMax RTO
。如果自从第一次传输数据以来,CFGY-ReTrExtTMO
时间就过去了,连接被关闭,即状态被设置为关闭。注意,当一个套接字被关闭时,将响应于接收到的端口所发送的任何数据包来发送重置。
当超时发生时,将重新发送输出窗口中的所有未确认数据。数据被重新打包,因此,包将不与原始包相同。例如,如果以10字节的数据发送分组,则发送具有30字节数据的分组,并且第一分组丢失,40字节的未确认数据将在输出窗口中。当超时发生时,所有40个字节将在一个分组中发送(假设MSS大于或等于40)。
如果接收到三个重复的确认,则快速重传算法无需等待超时即可重传TCP数据。RTIP32还实现了RFC 2582
中定义的NeReNeO
快速恢复算法。
类似场景:
client 连接服务器时,因 TLS
证书设置错误,所以会导致连接服务器后,没有收到应答;即发送 SYN 报文,无响应。
过滤实例
ip host 60.207.246.216 and icmp #表示只捕获主机IP为60.207.246.216的ICMP数据包。
ip.addr == 211.162.2.183 and icmp