macOS下安装与配置网络抓包工具Wireshark入门教程

最新下载的 Wireshark 需要 macOS 11.0 或更高版本。如果你的 macOS 版本较旧,可以通过 Homebrew 或 MacPorts 等其他包管理系统进行安装。

安装 Wireshark

install.png

  1. 将 Wireshark 应用程序拖动到“应用程序”文件夹中。
  2. 安装 ChmodBPF 包,为了能够捕获数据包,需要安装 ChmodBPF 包。
  3. 添加 Wireshark 到系统路径
    如果你希望将 Wireshark、TShark、capinfos、editcap 等命令行工具的路径添加到系统 PATH 中,可以安装“Add Wireshark to the system path”包。

卸载 Wireshark

要卸载 Wireshark,请执行以下操作:

  1. 删除 /Applications/Wireshark.app
  2. 删除 /Library/Application Support/Wireshark

卸载 ChmodBPF

你可以通过以下方式卸载 ChmodBPF:

  • 使用“Uninstall ChmodBPF”包,该包可以在当前磁盘或通过 Wireshark › About Wireshark › Folders › macOS Extras 找到。
  • 手动卸载:

    1. 卸载“org.wireshark.ChmodBPF.plist”启动守护进程。
    2. 删除 /Library/LaunchDaemons/org.wireshark.ChmodBPF.plist
    3. 删除“access_bpf”组。

卸载系统路径组件

你可以通过以下方式卸载系统路径组件:

  • 使用“Remove Wireshark from the system path”包,该包可以在当前磁盘或通过 Wireshark › About Wireshark › Folders › macOS Extras 找到。
  • 手动卸载:

    1. 删除 /etc/paths.d/Wireshark
    2. 删除 /etc/manpaths.d/Wireshark

运行及简单的入门

启动软件,选择对应的网卡,然后就可以开始抓包了...
start.png
主界面中一共分三大块:
第一块:分组的列表项,很多,有序号、时间、源地址、目的地址、协议、长度等
第二块:具体的某个分组的详细信息,具体对应网络分层,每一行信息自己看,截个图
第三块:以二进制显示,可以不用管

工具栏主要使用来控制抓包的,以上的图标按顺序依次是开始抓包、停止抓包、重新捕获、捕获选项(网卡、过滤器)、打开本地捕获文件、保存捕获文件、关闭捕获、重新加载捕获文件、搜索(过滤器),基本上的图标控制按钮就这么简单,后面的都是对界面的一些控制
tool.jpg

一些使用示例

  1. 比如我们在终端里ping www.baidu.com 然后我们就可以看到与之对应的IP请求
    ping.png
    然后我们看软件中,使用规则过滤一下对应的IP,毕竟默认的请求太多了...
    list.png
    然后我们还可以使用一些自带的过滤选择器...
    过滤.png
  2. 然后我们再来看个POST请求的抓包
    data.png

工具栏 

当进来时会进入欢迎页面,可以选择指定的网络接口(本地、wifi)或直接点击左上角的鲨鱼图标开始抓包。
005HV6Avgy1h7cm8lmc0jj315o02agnc.jpg
以上看到已经抓取了大量的网络数据包,下面开看看工具栏的作用

005HV6Avgy1h7cm6x7c2fj31wc15gb29.jpg
工具栏主要使用来控制抓包的,以上的图标按顺序依次是开始抓包、停止抓包、重新捕获、捕获选项(网卡、过滤器)、打开本地捕获文件、保存捕获文件、关闭捕获、重新加载捕获文件、搜索(过滤器),基本上的图标控制按钮就这么简单,后面的都是对界面的一些控制,没什么说的,自己动手试试即可。

过滤器 

当使用wireshark抓包时难免会有大量的抓包记录,而我们往往会针对某个网络包进行分析,而在这种大量数据下会严重影响到分析进度。为了避免其它数据造成的干扰,wireshark提供了过滤器来帮助过滤掉不必要的数据或只显示我们想要的数据。

过滤器分为捕获过滤器显示过滤器,而捕获过滤器又可以对网络接口和协议相关的两个维度的过滤。显示过滤器主要是对抓取到的网络数据包进行过滤显示,其针对的显示方面的的过滤,而捕获过滤器则是从源头进行过滤。网络接口主要告诉wireshark要抓取哪个接口的网络数据包如:wifi、本地回环、以太网、虚拟网、蓝牙等等,协议方面的选项通常告诉其抓取什么协议、什么端口、ip等等,如:TCP协议、HTTP协议、广播、ip等等。

在进入wireshark时的欢迎页面就可以对进行不同的接口进行选择,双击接口就可以抓取了,不需要选择时,默认会抓取所有接口的数据,可以直接点击左上角的鲨鱼按钮开始抓取。
005HV6Avgy1h7e4rn2cgqj31k413cdq0.jpg

除了在欢迎页选择不同的网络接口外,也可以在抓包页面上方的类似设置的按钮中,也可以选择不同的接口和详细的抓包选项,如下图:

005HV6Avgy1h7e5lo5e3vj31f00zak92.jpg

更详细过滤一些选项 
005HV6Avgy1h7e56c27ssj31hu0wk4c0.jpg

上面的过滤器我选择了抓取本地接口和端口为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

005HV6Avgy1h7e5xien0lj31jq0kye3e.jpg

现在看看当前的抓包情况,可以看到已经抓取到了,原地址和目标地址都是192.168.3.2本机局域网地址,还看到TCP协议、HTTP协议,如果现在只想分析HTTP协议的数据包呢,就可以用上显示过滤器了。设置它很简单,在记录上方的输入框即可过滤。如下图:显示http协议的请求。

005HV6Avgy1h7e65qwx1fj31dq0awjxz.jpg

以上还可以再细分,可以结合多个过滤选项使用and/or进行连接过滤,如http请求的携带了query

http and http and http.request.uri.query.parameter

这里过滤选项不需要记下来,点击输入框前面的小图标,可以列出不同的选项,点击后可以在输入框中添加.进行属性的进一步过滤。除了这个内置的显示过滤外,可以点击菜单栏的放大镜按钮,也会显示出过滤的输入框。这里相对来说有了更广的过滤条件,可以使用显示过滤、正则搜索、十六进制、字符串等等,点击搜索即可,搜索后并不会将不在范围的记录隐藏掉,而知识将目标高亮而已。

005HV6Avgy1h7e6bdfsdzj31iy0a245k.jpg

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地址了;如果在局域网中没找到响应的主机,交换机等会继续向上发送数据包直到找到位置。

005HV6Avgy1h7exa6rqjlj31qo0xcjvw.jpg

上图简单的画了请求的过程:

  1. 发送方ARP广播发送数据包请求到交换机
  2. 交换机转发给局域网内的主机
  3. 不是目标ip的主机丢弃掉数据包,目标ip主机接收数据包
  4. 目标主机以单播的形式回应发送方
小提示
在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缓存表中已经缓存了网关信息,接下来看看抓包情况:

005HV6Avgy1h7exxpipkwj31k60c2agi.jpg

ARP请求: 005HV6Avgy1h7exyt2n3ej31js0i07dz.jpg

ARP应答: 005HV6Avgy1h7exz8j210j31k00jq13r.jpg

从抓包数据可以看到,首先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头部。 005HV6Avgy1h7f8ebxzb4j30g905u40a.jpg

  • 源端口、目标端口: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 005HV6Avgy1h7f9dh3pluj31fm0p6476.jpg

三次握手 

这里使用curl发起服务请求

➜  curl http://localhost:9999
{"url":"/","host":"localhost:9999","user-agent":"curl/7.64.1","accept":"*/*"}%

看下抓包情况: 
005HV6Avgy1h7f9ovwy7kj31k60dwdur.jpg
从上图抓包记录可以将记录分为三部分:①TCP三次握手连接,②HTTP请求相关,③TCP四次挥手

下面这张图概况了三次握手的摘要 
005HV6Avgy1h7faoku3dyj31380lcdrx.jpg
抓包记录:
005HV6Avgy1h7f9rj9jobj30ss03qtb1.jpg

  1. 这里看出两端通信的端口为54987(终端)和9999(服务器),终端发送SYN类型请求,指明客户端的初始化序号为0,这里的0位相对值,其真实性值为3059428279,并告诉下次的序列号为1,如下图:
    005HV6Avgy1h7f9zshnzlj311s0go102.jpg
  2. 服务端接收到客户端的SYN数据包后,发送自己的应答SYN包,并指定自己的序列号0(真实值3338838224),并将客户端的序列号+1发送ACK=1确认包(acknumber=3059428280),并告诉下次序列号为1,如下图:
    005HV6Avgy1h7fa53pnh8j312a0jywnv.jpg
  3. 客户端接收到了服务端的SYN数据包和ACK包后,也将服务端的SYN+1(acknumber = 3338838225)作为ACK数据包发送给服务端,就完成了三次握手
    005HV6Avgy1h7fagk4km2j31280kewn3.jpg

至于ACK值不断加1是为了标识数据包保证接收方的顺序性,因为发送时数据可能乱序,在收到数据后,TCP不会直接把数据交给上层,而会做一个缓存,直到传输完毕将包按顺序组装在上交给应用层。

三次握手的简单理解: 第一次:客户端发送数据到服务端,服务端接收到后知道客户端的发送能力没问题 第二次:服务端发送数据到客户端,客户端接接收后知道服务端的接收能力正常,发送能力也没问题 第三次:客户端再发送数据到服务端,服务端接收后知道客户端的接收能力没问题

通过三次握手两端都知道了对方发送和接收没有问题,之后就可以正常通信了。

四次挥手 

当客户端请求毕后就会断开连接,由于为了提高传输效率http使用keep-alive会在一定时间内保持TCP的连接,这里设置HTTP头部connection=close表示请求完毕后立即断开连接。

来看回收抓包记录:
005HV6Avgy1h7fb5u12owj30yg04on1o.jpg

  1. 在客户端请求完毕后会发送FIN报文给服务端,包含自己的序列号seq=79和ack=125来确认对方最近一次发送的数据,然后表示我没有其他请求了,这时客户端进入FIN_WAIT1状态 
    005HV6Avgy1h7fbdyp9zzj31200hyjyp.jpg
  2. 服务端接收到数据包后,发送包含自己的seq=125和ack=80的ACK报文给客户端,表示我知道了,并通知上层应用另一端发起了关闭操作,此时服务端并不会立马发起关闭操作,也就是发送服务端的FIN报文,此时服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态 
    005HV6Avgy1h7fbhbhh94j31240hwn4s.jpg
  3. 等一会时间服务端再发送包含seq=125,ack=80的FIN报文和ACK报文并期待下一次的ACK序列号为126,表示可以断开连接了,服务端进入LAST_ACK状态
    005HV6Avgy1h7fbkn6yf5j311g0g2wlf.jpg
  4. 客户端接收到后会在发送ack=126的ACK报文,最后断开连接,此时客户端进入TIMED_WAIT状态,服务端将会进入CLOSED状态,最后再等2MSL(Maximum Segment Lifetime)客户端也进入CLOSED状态 
    005HV6Avgy1h7fbm614fxj311k0gatem.jpg

通过上面的分析已经对四次挥手有了更深理解了,下面再画个图总结下 
005HV6Avgy1h7fccd75wkj31gi0qutn3.jpg

以上就是TCP挥手的基本原理了。这里解释一下两个问题:

  1. 为什么挥手要四次,而握手是3次? 因为握手时服务端直接确认连接不需要等待,所以发送SYN+ACK数据包。而挥手时服务端接受到了客户端的FIN包后,知道客户端没有请求了但还可以继续接受数据包,服务端也并不能立马关闭连接,因为服务端此时可能数据并没有发送完毕,需要等待发送完毕后才会主动发送FIN包请求断开。
  2. 为什么客户端挥手后发送了ACK包还要等2MSL段时间才会进入CLOSED状态? 这是因为当客户端发送了ACK报文后,有可能有丢失的包的可能,这导致服务端还没有收到客户端的ACK报文,会认为自己发的FIN报文可能客户端没有收到,于是会再发一个给客户端,客户端会再发送ACK报文,重新计时2MSL,等服务端接收到ACK报文后,则不会再发送FIN报文,2MSL时间段后客户端正式进入CLOSED状态。

HTTP协议 

由于HTTP协议是基于TCP协议的,所以上面我们用curl发起的是HTTP请求,那我们看下http请求过程。
005HV6Avgy1h7fcums2gkj30vq04edig.jpg

  • 首先客户端发送GET请求给服务端
  • 服务端发送TCP的ACK的数据包确认已经收到请求了
  • 服务端发送http响应,状态码200
  • 客户端接收到后,发送TCP的ACK数据包表示已经接收到了数据

我们通过跟踪HTTP数据流看下细节:
005HV6Avgy1h7fcww5re2j311m0f2afi.jpg

到这里已经了解了如何用wireshark分析ARP协议、TCP协议和HTTP协议了,当然这只是简单的讲解,其他协议都大同小异,更多功能自己可以动手试试。

标签: macOS, 测试, 运维

相关文章

macOS下安装与配置网络抓包工具Charles入门教程

charles抓包工具是基于HTTP请求中间人代理,通过和服务端、客户端建立通信将客户端的请求数据发送服务器,并将响应数据传输给客户端,实现抓包记录,最最最...我想推荐的原因是...它很简洁....

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件