tcpdump、wireshark 抓包分析(小白快速上手)

发布时间:2024年01月23日

什么是抓包


网络世界中的数据包一般都是不可见的,导致在学习计算机网络的时候会觉得其非常抽象,加大了学习的难度。

自从有了网络包分析工具:tcpdump 和 Wireshark,使不可见的数据包得以可视化。

问题:tcpdump 和 wireshark 有什么区别?

tcpdump 和 wireshark 是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。

1)tcpdump 仅支持命令行格式使用,常在 Linux 服务器中抓取和分析网络包;

2)wireshark 除了可以抓包外,还提供了可视化分析网络包的图形页面(更加直观);

所以,这两者往往是搭配使用的,先用 tcpdump 命令在 Linux 服务器上抓包,接着把抓包的文件 copy 到 windows 电脑后,用 wireshark 进行可视化分析。

当然,如果你是在 windows 上抓包,只需要用 wireshark 工具就可以了。

问题:tcpdump 在 Linux 下如何抓包?

tcpdump 提供了大量的选项以及各式各样的过滤表达式,来帮助你抓取指定的数据包,不过不要担心,只需要掌握一些常用选项和过滤表达式,就可以满足大部分场景的需要了。

tcpdump 如何使用


tcpdump 是一款用于截取网络分组,并输出分组内容的工具,可以用于网络故障排查、分析以及实现网络安全监控。它能够捕获网络上传输的数据包,并提供了强大的过滤功能,允许用户根据特定的需求进行定制化过滤,从而只捕获需要的网络流量。tcpdump 提供了灵活的截取策略,支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来帮助用户去掉无用的信息。由于其强大的功能和灵活的截取策略,tcpdump 成为类 UNIX 系统下用于网络分析和问题排查的首选工具。

tcpdump 语法


tcpdump [-adeflnNOpqStvx] [-c <数据包数目>] [-dd] [-ddd] [-F <表达文件>] [-i <网络界面>] [-r <数据包文件>] [-s <数据包大小>] [-tt] [-T <数据包类型>] [-vv] [-w <数据包文件>] [输出数据栏位]

参数说明:

1)[-adeflnNOpqStvx]

  • -a 尝试将网络和广播地址转换成名称;
  • -d 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出;
  • -e 在每列倾倒资料上显示连接层级的文件头;
  • -f 用数字显示网际网络地址;
  • -l 使用标准输出列的缓冲区;
  • -n 不把主机的网络地址转换成名字;
  • -N 不列出域名;
  • -O 不将数据包编码最佳化;
  • -p 不让网络界面进入混杂模式;
  • -q 快速输出,仅列出少数的传输协议信息;
  • -S 用绝对而非相对数值列出TCP关联数;
  • -t 在每列倾倒资料上不显示时间戳记;
  • -v 详细显示指令执行过程;
  • -x 用十六进制字码列出数据包资料;

2)[-c ]:-c 收到指定的数据包数目后,就停止进行倾倒操作;

3)[-dd]:-dd 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出;

4)[-ddd]:-ddd 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出;

5)[-F ]:-F 指定内含表达方式的文件;

6)[-i ]:-i 使用指定的网络截面送出数据包;

7)[-r ]:-r 从指定的文件读取数据包数据;

8)[-s ]:-s 设置每个数据包的大小;

9)[-tt]:-tt 在每列倾倒资料上显示未经格式化的时间戳记;

10)[-T ]:-T 强制将表达方式所指定的数据包转译成设置的数据包类型;

11)[-vv]:-vv 更详细显示指令执行过程;

12)[-w ]:-w 把数据包数据写入指定的文件;

tcpdump 如何抓包


假设我们要抓取下面 ping 的数据包:

root@BZD25521:~# ping -I eth0 -c 3 baidu.com
PING baidu.com (110.242.68.66) from 172.27.142.199 eth0: 56(84) bytes of data.
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=52 time=30.0 ms
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=2 ttl=52 time=29.5 ms
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=3 ttl=52 time=101 ms

--- baidu.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 29.545/53.613/101.329/33.740 ms

要抓取上面 ping 命令的数据包,首先我们要知道 ping 的数据包是 icmp 协议,接着在使用 tcpdump 抓包的时候,就可以指定只抓 icmp 协议的数据包,具体命令如下:

tcpdump -i eth0 icmp and host 172.27.142.199 -nn

问题:上述抓包命令参数含义是什么?

1)-i eth0 表示抓取 eth0 网口的数据包;

2)icmp 表示抓取 icmp 协议的数据包;

3)host 表示主机过滤,抓取对应 IP 的数据包;

4)-nn 表示不解释 IP 地址和端口号名称;

抓包具体操作流程如下:

1)在终端一中执行 tcpdump 抓包命令,等待抓包

tcpdump -i eth0 icmp and host 172.27.142.199 -nn

执行结果如下:

2)在终端二中执行 ping 命令

 ping -I eth0 -c 3 baidu.com

执行结果如下:

3)在终端一中停止抓包

Ctrl + C

执行结果如下:

从 tcpdump 抓取的 icmp 数据包,可以清楚的看到 icmp echo 的交互过程,首先发送方发起了 ICMP echo request 请求报文,接收方收到后回了一个 ICMP echo reply 响应报文,之后 seq 是递增的。

数据包格式


当 tcpdump 抓取到 icmp 数据包后,其输出格式如下:

时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息

tcpdump 常见用法


tcpdump 抓包常用命令参数如下表所示:

tcpdump 使用 —— 选项类

选项

示例

说明

-i

tcpdump -i eth0

指定网络接口,默认是 0 号接口(如 eth0),any 表示所有接口

-c

tcpdump -c 5

限制要抓取的网络包个数

-nn

tcpdump -nn

不解析 IP地址和端口号名称

-w

tcpdump -w file.pcap

把 tcpdump 抓取到的数据包保存到 file.pcap 文件中

接下来,我们再来看看常用的过滤包用法,在上面的 ping 例子中,我们用的是 icmp and host 172.27.142.199,表示抓取 icmp 协议的数据包,以及源地址或目标地址为 172.27.142.199 的包。其他常用的过滤选项如下表所示:

tcpdump 使用 —— 过滤表达式类

选项

示例

说明

host、src host、dst host

tcpdump -nn host 172.27.142.199

主机过滤

port、src port、dst port

tcpdump -nn port 80

端口过滤

ip、ip6、arp、tcp、udp、icmp

tcpdump -nn tcp

协议过滤

and、or、not

tcpdump -nn host 172.27.142.199 and port 80

逻辑表达式过滤

tcp[tcoflages]

tcpdump -nn "tcp[tcoflages] & tcp-syn != 0"

特定状态的 tcp 包

从上面的介绍可以发现,虽然 tcpdump 功能强大,但其输出格式并不直观。所以,在工作中 tcpdump 只是用来抓取数据包,不用来分析数据包,而是把 tcpdump 抓取的数据包保存成 .pcap 格式的文件,接着用 wireshark 工具进行数据包可视化分析。

wireshark 如何使用


wireshark 除了可以抓包外,还提供了可视化分析网络包的图形页面,同时,还内置了一系列的汇总分析工具。拿上面的 ping 例子来说,我们可以使用下面的命令,把抓取的数据包保存到 ping.pcap 文件,然后使用 wireshark 工具进行可视化分析。

具体操作流程如下:

1)在终端一中执行 tcpdump 抓包命令,等待抓包

tcpdump -i eth0 icmp and host 172.27.142.199 -w /root/ping.pcap

执行结果如下:

2)在终端二中执行 ping 命令

 ping -I eth0 -c 3 baidu.com

执行结果如下:

3)在终端一中停止抓包

Ctrl + C

执行结果如下:

把 ping.pcap 文件 copy 到 windows 下,然后用 wireshark 打开它,将看到如下界面:

在 Wireshark 页面里,可以更加直观的分析数据包,不仅展示各个网络包的头部信息,还会用不同的颜色来区分不同的协议,由于这次抓包只有 ICMP 协议,所以只有紫色的条目。

接着,在网络包列表中选择某一个网络包后,在其下面的网络包详情中,可以更清楚的看到,这个网络包在协议栈各层的详细信息。以编号 1 的网络包为例:

1)在数据链路层,可以看到 MAC 包头信息,如:源 MAC 地址和目标 MAC 地址等字段;

2)在 IP 层,可以看到 IP 包头信息,如:源 IP 地址和目标 IP 地址、TTL、IP 包长度、协议等 IP 协议各个字段的数值和含义;

3)在 ICMP 层,可以看到 ICMP 包头信息,比如 Type、Code 等 ICMP 协议各个字段的数值和含义;

wireshark 用了分层的方式,展示了各个层的包头信息,把“不可见”的数据包进行了可视化。

从 ping 的例子中,我们可以看到网络分层就像有序的分工,每一层都有自己的责任范围和信息,上层协议完成工作后就交给下一层,最终形成一个完整的网络包。

MySQL 协议抓包分析


注:使用 tcpdump 抓取 MySQL 协议包之前需要关闭 SSL 连接;否则因为 SSL 加密机制,无法抓取 MySQL 协议包!

tcpdump 抓包


1)在终端一启动抓包命令

tcpdump -i any tcp and host 127.0.0.1 and port 3306 -w /root/test.pcap

执行结果如下:

2)在终端二中执行如下命令

1) 启动 MySQL
2) 登陆 MySQL
3) 进行一些简单操作
4) 退出并关闭 MySQL

执行结果如下:

3)在终端一中停止 tcpdump 抓包

Ctrl + C

执行结果如下:

wireshark 分析数据包


使用 wireshark 打开 test.pacp 文件,界面如下:

MySQL 是基于 TCP 协议进行传输的,MySQL 客户端与服务器端交互过程如下:

由 wireshark 抓包分析和 MySQL 客户端与服务器端交互过程可知:

1)最开始的 3 个包是 TCP 三次握手建立连接的包;

2)4~20 是 MySQL 握手认证阶段建立的包;

上述 4~20 数据包分别对应:

  • 服务器 ===> 客户端:握手初始化消息;由 MySQL 服务器主动发送一个认证的握手数据包;
  • 客户端 ===> 服务端:登陆认证消息;客户端收到握手数据包后,将用户的信息(用户名、密码、数据库等信息)打包发送给 MySQL 服务器;
  • 服务端 ===> 客户端:认证结果消息;MySQL 服务端认证,返回认证结果给客户端;
    • 认证成功:如果服务器通过认证,则发送一个 Ok_pack 包给客户端;
    • 认证失败:如果服务器没有通过认证,,则发送一个 error_pack 包;

问题:握手认证阶段数据包各参数含义是什么?

1)Server Greeting proto=10 version=5.7.39-debug

  • proto=10 是指协议版本号;
  • version=5.7.39-debug 是指服务器版本号;

2)50156 → 3306 [ACK] Seq=1 Ack=85 Win=65536 Len=0 TSval=3380584881 TSecr=3380584881

  • 50156 是 TCP 序列号,每个 TCP 段都有一个序列号,用于标识该段数据在字节流中的位置;
  • → 表示数据是从哪个方向发送的;
  • 3306 是 MySQL 端口号,表示接收该数据的应用程序端口;
  • Ack 表示是一个确认段;
  • Seq 序列号的缩写,表示该段数据的起始序列号,Seq=1 意味着这是从序列号为 0 的数据段之后发送的第一个数据段;
  • Ack=85 表示接收端期望接收的下一个数据段的序列号,在这个例子中,它是 85,意味着接收端期望接收序列号为 85 的数据段;
  • Win=65536 Win?是窗口大小的缩写,这个字段表示接收端为该连接分配的 TCP 接收窗口的大小;窗口大小是动态变化的,用于流量控制和拥塞控制。65536通常表示一个较大的窗口大小;
  • 表示该段数据的长度(以字节为单位),在这个例子中,它是 0,意味着该段没有携带任何应用层数据;
  • TSval=3380584881 是发送时间戳;
  • TSecr=3380584881 是接收时间戳;这两个时间戳用于计算往返时间和重复数据包;

3)Login Request user=:当客户端与服务器尝试进行连接时,它会发送一个 Login Request 数据包,包中,user= 通常表示客户端正在尝试使用一个用户名进行身份验证;服务器会检查这个用户名,并与存储在服务器上的用户数据库进行比较,以确定客户端是否有权访问服务器上的资源;

4)Client Hello:客户端向服务器发送的第一条消息,用于握手认证,数据包中包含了客户端权能标志、最大消息长度、字符编码等(即登陆认证报文);

3)20~20021 是 MySQL 命令执行阶段建立的包;

4)20021~20024 是 TCP 四次挥手建立的包;

问题:为什么 tcpdump 抓包抓到的 TCP 挥手是三次,而不是四次?

当被动关闭方在 TCP 挥手过程中,「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手

而通常情况下,服务器端收到客户端的 FIN 后,很可能还没发送完数据,所以就会先回复客户端一个 ACK 包,稍等一会儿,完成所有数据包的发送后,才会发送 FIN 包,这也就是四次挥手了。

此外,Wireshark 可以用时序图的方式显示数据包交互的过程,从菜单栏中,点击 统计 (Statistics) -> 流量图 (Flow Graph),然后,在弹出界面中的「流量类型」选择「TCP Flows」,你可以更清晰的看到,整个过程中 TCP 流的执行过程:

问题:为什么 TCP 三次握手过程中 Seq 是 0?

实际上是因为 Wireshark 工具帮我们做了优化,它默认显示的是序列号 Seq 是相对值,而不是真实值。

如果你想看到实际的序列号的值,可以右键菜单, 然后找到「协议首选项」、「Transmission Control Protocol」,接着找到「Relative Seq」后,把它给取消勾选(取消 Seq 相对值的显示方式),操作如下:

取消后,Seq 显示的就是真实值了,具体如下图所示:

可见,客户端和服务端的序列号实际上是不同的,序列号是一个随机值。

这其实跟我们书上看到的 TCP 三次握手和四次挥手很类似,作为对比,你通常看到的 TCP 三次握手和四次挥手的流程,基本是这样的:

说明:client_isn 是客户端初始化的序列号、server_isn 是服务端初始化的序列号;

文章来源:https://blog.csdn.net/weixin_47156401/article/details/135791620
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。