macOS下安装与配置网络抓包工具Wireshark入门教程
最新下载的 Wireshark 需要 macOS 11.0 或更高版本。如果你的 macOS 版本较旧,可以通过 Homebrew 或 MacPorts 等其他包管理系统进行安装。
安装 Wireshark
- 将 Wireshark 应用程序拖动到“应用程序”文件夹中。
- 安装 ChmodBPF 包,为了能够捕获数据包,需要安装 ChmodBPF 包。
- 添加 Wireshark 到系统路径
如果你希望将 Wireshark、TShark、capinfos、editcap 等命令行工具的路径添加到系统 PATH 中,可以安装“Add Wireshark to the system path”包。
卸载 Wireshark
要卸载 Wireshark,请执行以下操作:
- 删除
/Applications/Wireshark.app
。 - 删除
/Library/Application Support/Wireshark
。
卸载 ChmodBPF
你可以通过以下方式卸载 ChmodBPF:
- 使用“Uninstall ChmodBPF”包,该包可以在当前磁盘或通过 Wireshark › About Wireshark › Folders › macOS Extras 找到。
手动卸载:
- 卸载“org.wireshark.ChmodBPF.plist”启动守护进程。
- 删除
/Library/LaunchDaemons/org.wireshark.ChmodBPF.plist
。 - 删除“access_bpf”组。
卸载系统路径组件
你可以通过以下方式卸载系统路径组件:
- 使用“Remove Wireshark from the system path”包,该包可以在当前磁盘或通过 Wireshark › About Wireshark › Folders › macOS Extras 找到。
手动卸载:
- 删除
/etc/paths.d/Wireshark
。 - 删除
/etc/manpaths.d/Wireshark
。
- 删除
运行及简单的入门
启动软件,选择对应的网卡,然后就可以开始抓包了...
主界面中一共分三大块:
第一块:分组的列表项,很多,有序号、时间、源地址、目的地址、协议、长度等
第二块:具体的某个分组的详细信息,具体对应网络分层,每一行信息自己看,截个图
第三块:以二进制显示,可以不用管
工具栏主要使用来控制抓包的,以上的图标按顺序依次是开始抓包、停止抓包、重新捕获、捕获选项(网卡、过滤器)、打开本地捕获文件、保存捕获文件、关闭捕获、重新加载捕获文件、搜索(过滤器),基本上的图标控制按钮就这么简单,后面的都是对界面的一些控制
一些使用示例
- 比如我们在终端里
ping www.baidu.com
然后我们就可以看到与之对应的IP请求
然后我们看软件中,使用规则过滤一下对应的IP,毕竟默认的请求太多了...
然后我们还可以使用一些自带的过滤选择器... - 然后我们再来看个POST请求的抓包
工具栏
当进来时会进入欢迎页面,可以选择指定的网络接口(本地、wifi)或直接点击左上角的鲨鱼图标开始抓包。
以上看到已经抓取了大量的网络数据包,下面开看看工具栏的作用
工具栏主要使用来控制抓包的,以上的图标按顺序依次是开始抓包、停止抓包、重新捕获、捕获选项(网卡、过滤器)、打开本地捕获文件、保存捕获文件、关闭捕获、重新加载捕获文件、搜索(过滤器),基本上的图标控制按钮就这么简单,后面的都是对界面的一些控制,没什么说的,自己动手试试即可。
过滤器
当使用wireshark抓包时难免会有大量的抓包记录,而我们往往会针对某个网络包进行分析,而在这种大量数据下会严重影响到分析进度。为了避免其它数据造成的干扰,wireshark提供了过滤器来帮助过滤掉不必要的数据或只显示我们想要的数据。
过滤器分为捕获过滤器和显示过滤器,而捕获过滤器又可以对网络接口和协议相关的两个维度的过滤。显示过滤器主要是对抓取到的网络数据包进行过滤显示,其针对的显示方面的的过滤,而捕获过滤器则是从源头进行过滤。网络接口主要告诉wireshark要抓取哪个接口的网络数据包如:wifi、本地回环、以太网、虚拟网、蓝牙等等,协议方面的选项通常告诉其抓取什么协议、什么端口、ip等等,如:TCP协议、HTTP协议、广播、ip等等。
在进入wireshark时的欢迎页面就可以对进行不同的接口进行选择,双击接口就可以抓取了,不需要选择时,默认会抓取所有接口的数据,可以直接点击左上角的鲨鱼按钮开始抓取。
除了在欢迎页选择不同的网络接口外,也可以在抓包页面上方的类似设置的按钮中,也可以选择不同的接口和详细的抓包选项,如下图:
更详细过滤一些选项
上面的过滤器我选择了抓取本地接口和端口为9999的数据包,这里我用Nodejs
监听9999
端口号开启了一个web服务,接着用curl请求这个地址:
➜ curl -I 192.168.3.2:9999 # 请求成功
HTTP/1.1 200 OK
X-Powered-By: Express
Set-Cookie: __ut=123456; Path=/
Content-Type: application/json; charset=utf-8
Content-Length: 79
ETag: W/"4f-IdYGYravFqZ+6sBfe27/eQDuPDo"
Date: Sat, 22 Oct 2022 08:46:19 GMT
Connection: keep-alive
Keep-Alive: timeout=5
现在看看当前的抓包情况,可以看到已经抓取到了,原地址和目标地址都是192.168.3.2
本机局域网地址,还看到TCP协议、HTTP协议,如果现在只想分析HTTP协议的数据包呢,就可以用上显示过滤器了。设置它很简单,在记录上方的输入框即可过滤。如下图:显示http
协议的请求。
以上还可以再细分,可以结合多个过滤选项使用and
/or
进行连接过滤,如http请求的携带了query
http and http and http.request.uri.query.parameter
这里过滤选项不需要记下来,点击输入框前面的小图标,可以列出不同的选项,点击后可以在输入框中添加.
进行属性的进一步过滤。除了这个内置的显示过滤外,可以点击菜单栏的放大镜按钮,也会显示出过滤的输入框。这里相对来说有了更广的过滤条件,可以使用显示过滤、正则搜索、十六进制、字符串等等,点击搜索即可,搜索后并不会将不在范围的记录隐藏掉,而知识将目标高亮而已。
ARP协议
通过前面的学习你应该对wireshark这款软件的抓包基本功能有了了解,现在就来使用它来抓取数据包分析吧,本文会分别介绍ARP协议、TCP协议等网络协议,让我们以ARP协议开始吧。
在抓包开始前首先要明白什么是ARP协议,了解协议本身有助于我们抓取的准备和方向,这里简单的概述下。
ARP是地址解析协议,从协议层次角度是个网络层协议,功能角度是链路层协议,用来查询ip所对应的mac地址。在互联网通信中,主机与主机之间通信,都是通过OSI模型从上到下的协议将数据封装最终发送到目的主机,通常情况下我们常见的是对应主机的ip,然后就可以知道目标主机的位置了,但这只是表面上的,通信双方还需要知道双方的mac地址才能通信,没有mac地址就像快递只写了收件人姓名,却没有收件地址一样。
上层应用程序只关心ip地址而不关系mac地址,mac地址需要通过ARP协议获取目标主机地址,完成数据的封装。那么ARP协议是如何获取目标主机的mac地址的,假如这里有两台机器:p1的ip地址192.168.3.1
,p2的ip地址192.168.3.2
,当p1想和p2通信时,从OSI协议封装顺序发送方自顶向下封装数据,ARP从上层知道了p2的目标ip地址,然后封装ARP数据包,将自己的ip地址和mac地址和对方的ip和mac占位地址封装,然后通过以太网的广播形式发送出去,交换机、网关或路由器等设备接收到广播包后,会将数据发给同一局域网的其他主机,当不同的主机接受到广播包后,会判断自己是不是这个发送者寻找的ip,如果不是则会将包丢弃掉不做任何应答;而如果当前主机和目的ip一致的话,将会接受此包并将自己的mac地址封装进去,并以单播的形式回应发送主机方,发送主机方就会知道目标ip所对应的mac地址了;如果在局域网中没找到响应的主机,交换机等会继续向上发送数据包直到找到位置。
上图简单的画了请求的过程:
- 发送方ARP广播发送数据包请求到交换机
- 交换机转发给局域网内的主机
- 不是目标ip的主机丢弃掉数据包,目标ip主机接收数据包
- 目标主机以单播的形式回应发送方
小提示
在ARP请求广播过程中,途径的网关和其他接收到广播的主机虽然不是目标主机,但也会在自己的ARP缓存表中记住发送方的ip和mac地址,这是方便以后其他主机向目标主机通信。
当目标主机找到后,也会记住发送方的ip和mac地址,然后将自己的mac地址和ip地址封装数据后以单播的形式回应发送给发送方。
接下来就用wireshark抓包看看实际的网络请求情况,这里一台机器的ip为192.168.3.8
,现在让它请求网关192.168.3.1
,这里使用linux的nmap扫描工具扫描网关。
首先先打开wireshark监听抓包,这里直接抓取所有的接口,在显示过滤器中输入ARP
协议来过滤显示ARP协议的数据包。
nmap 192.168.3.1 # 然后会找到以下信息
# Starting Nmap 7.70 ( https://nmap.org ) at 2022-10-22 22:02 CST
# Nmap scan report for 192.168.3.1
# Host is up (0.0070s latency).
# Not shown: 972 closed ports
# PORT STATE SERVICE
# 3/tcp filtered compressnet
# 53/tcp open domain
# 80/tcp open http
# ....
arp -a # 查看ARP缓存表信息
# ➜ arp -a
# _gateway (192.168.3.1) at dc:33:xx:xx:xx:07 [ether] on enp0s5 # 这里就是网关被找到了
# ? (192.168.3.2) at 38:f9:xx:xx:05:db [ether] on enp0s5
上面通过扫描工具扫描网关,再查看ARP缓存表中已经缓存了网关信息,接下来看看抓包情况:
ARP请求:
ARP应答:
从抓包数据可以看到,首先Apple
(192.168.3.8)主机以广播的形式发送数据包,ARP请求数据包中有自己的Send MAC address、ip address还有目标主机的ip192.168.3.1
和mac地址00:00:00:00:00:00
(这里0表示坑位待目标填写),携带信息Who has 192.168.3.1? tell 192.168.3.8
。当Huawei
(网关192.168.3.1)接受到Apple
发送来的数据包后,将自己的mac地址封装仅需其他的保持不变,再以单播的形式发送ARP Reply数据包,携带信息192.168.3.1 at xx:xx:xx:xxx
,这样在Apple
接收到数据包后就知道了目标的Mac地址了,就可以进行数据发送了。
这里简单说下ARP数据包中一些字段:
- Hardware type:硬件类型(标识链路层协议)
- Protocol type:协议类型(标识网络层协议)
- Hardware size:硬件地址大小(标识mac地址长度),这里是6字节,48bit
- Protocol size:协议地址大小(表示ip地址长度),这里是4字节,32bit
- Opcode:操作码(表示ARP请求类型),1表示请求,2表示应答
- Sender Mac address:发送者mac地址
- Sender IP address:发送者ip地址
- Target MAC address:目标mac地址
- Target IP address:目标ip地址
以上便是ARP协议的基本原理,通过nmap扫描工具,再用wireshark进行抓包分析后应该已经对ARP协议不陌生了,基本就是一问一答简单形式。当然这里主要还是讲wireshark怎么抓取ARP数据包,来理解ARP的简单概念,至于ARP的更详细的概念可以看看其他文章,如果没有后面也会更新相关文章。
TCP协议
TCP协议是基于字节流面向连接、可靠的、全双工的单播协议,在通信前必须建立连接,也就是常说的三次握手,然后会断开进行四次挥手。我们来先了解下TCP头部。
- 源端口、目标端口:TCP里没有源IP和目的IP,这是IP层协议的事情,源IP、源端口、目标IP、目标端口构成了TCP
四元组
,一个四元组可以标识一个连接。 - 序列号:用于确认包的的顺序,序列号加上报文长度,用于确定传输的是哪一段数据。
- 确认号:TCP使用确认号来告知对方下一个期望接受的序列号
标志位:用来发起连接同步初始序列号,有些用来确认数据包,还有用来结束连接的
- SYN:用于发起连接数据包同步初始序列号
- ACK:确认数据,只有当ACK=1时有效
- RST:强制断开连接
- FIN:告知对方数据发送完毕,准备断开连接
- PSH:告知对方数据包收到后马上交给应用层,不能缓存
- 窗口大小:用来控制对方发送的数据量
更多TCP的详细内容请查看我的「TCP协议」一文
上面简单的介绍了TCP头部部分信息,TCP的连接由发送SYN开始,结束时通过FIN断开连接。下面我们就通过wireshark进行抓包分析。因为HTTP请求也是基于TCP协议的,这里以HTTP请求为例展开三次握手和四次挥手的细节。
这里开启一个node服务作为web服务器:
const express = require("express")
const app = express()
const port = process.env.PORT || 9999
app.use(async (req, res, next) => {
res.setHeader("connection", "close")
res.json({
url: req.url,
...req.headers,
...req.query
})
})
app.listen(port, () => {
console.log(`Server is running on port ${port}`)
});
wireshark我们选择本地回环地址网卡接口,端口选择9999
三次握手
这里使用curl
发起服务请求
➜ curl http://localhost:9999
{"url":"/","host":"localhost:9999","user-agent":"curl/7.64.1","accept":"*/*"}%
看下抓包情况:
从上图抓包记录可以将记录分为三部分:①TCP三次握手连接,②HTTP请求相关,③TCP四次挥手
下面这张图概况了三次握手的摘要
抓包记录:
- 这里看出两端通信的端口为
54987
(终端)和9999
(服务器),终端发送SYN
类型请求,指明客户端的初始化序号为0,这里的0位相对值,其真实性值为3059428279
,并告诉下次的序列号为1,如下图: - 服务端接收到客户端的SYN数据包后,发送自己的应答SYN包,并指定自己的序列号0(真实值3338838224),并将
客户端的序列号+1发送ACK=1确认包(acknumber=3059428280)
,并告诉下次序列号为1,如下图: - 客户端接收到了服务端的SYN数据包和ACK包后,也将服务端的SYN+1(acknumber = 3338838225)作为ACK数据包发送给服务端,就完成了三次握手
至于ACK值不断加1是为了标识数据包保证接收方的顺序性,因为发送时数据可能乱序,在收到数据后,TCP不会直接把数据交给上层,而会做一个缓存,直到传输完毕将包按顺序组装在上交给应用层。
三次握手的简单理解: 第一次:客户端发送数据到服务端,服务端接收到后知道客户端的发送能力没问题 第二次:服务端发送数据到客户端,客户端接接收后知道服务端的接收能力正常,发送能力也没问题 第三次:客户端再发送数据到服务端,服务端接收后知道客户端的接收能力没问题
通过三次握手两端都知道了对方发送和接收没有问题,之后就可以正常通信了。
四次挥手
当客户端请求毕后就会断开连接,由于为了提高传输效率http使用keep-alive
会在一定时间内保持TCP的连接,这里设置HTTP头部connection=close
表示请求完毕后立即断开连接。
来看回收抓包记录:
- 在客户端请求完毕后会发送FIN报文给服务端,包含自己的序列号seq=79和ack=125来确认对方最近一次发送的数据,然后表示我没有其他请求了,这时客户端进入
FIN_WAIT1
状态 - 服务端接收到数据包后,发送包含自己的seq=125和ack=80的ACK报文给客户端,表示我知道了,并通知上层应用另一端发起了关闭操作,此时服务端并不会立马发起关闭操作,也就是发送服务端的FIN报文,此时服务端进入
CLOSE_WAIT
状态,客户端进入FIN_WAIT2
状态 - 等一会时间服务端再发送包含seq=125,ack=80的FIN报文和ACK报文并期待下一次的ACK序列号为126,表示可以断开连接了,服务端进入
LAST_ACK
状态 - 客户端接收到后会在发送ack=126的ACK报文,最后断开连接,此时客户端进入
TIMED_WAIT
状态,服务端将会进入CLOSED
状态,最后再等2MSL
(Maximum Segment Lifetime)客户端也进入CLOSED
状态
通过上面的分析已经对四次挥手有了更深理解了,下面再画个图总结下
以上就是TCP挥手的基本原理了。这里解释一下两个问题:
- 为什么挥手要四次,而握手是3次? 因为握手时服务端直接确认连接不需要等待,所以发送
SYN+ACK数据包
。而挥手时服务端接受到了客户端的FIN
包后,知道客户端没有请求了但还可以继续接受数据包,服务端也并不能立马关闭连接,因为服务端此时可能数据并没有发送完毕,需要等待发送完毕后才会主动发送FIN
包请求断开。 - 为什么客户端挥手后发送了
ACK
包还要等2MSL
段时间才会进入CLOSED
状态? 这是因为当客户端发送了ACK
报文后,有可能有丢失的包的可能,这导致服务端还没有收到客户端的ACK
报文,会认为自己发的FIN
报文可能客户端没有收到,于是会再发一个给客户端,客户端会再发送ACK
报文,重新计时2MSL
,等服务端接收到ACK
报文后,则不会再发送FIN
报文,2MSL
时间段后客户端正式进入CLOSED
状态。
HTTP协议
由于HTTP协议是基于TCP协议的,所以上面我们用curl
发起的是HTTP请求,那我们看下http请求过程。
- 首先客户端发送GET请求给服务端
- 服务端发送TCP的ACK的数据包确认已经收到请求了
- 服务端发送http响应,状态码200
- 客户端接收到后,发送TCP的ACK数据包表示已经接收到了数据
我们通过跟踪HTTP数据流看下细节:
到这里已经了解了如何用wireshark分析ARP协议、TCP协议和HTTP协议了,当然这只是简单的讲解,其他协议都大同小异,更多功能自己可以动手试试。
版权声明:本文为原创文章,版权归 全栈开发技术博客 所有。
本文链接:https://www.lvtao.net/tool/macos-wireshark.html
转载时须注明出处及本声明