零、前言
本书的目的是识别、了解和解决与协议、网络和安全相关的问题,并了解 Wireshark 如何通过允许其功能有效地进行故障排除来帮助分析这些模式。这本书有实验练习,并包含离线查看和分析的数据包捕获文件。大多数示例包含类似生产的场景及其解决方案和重现这些解决方案的步骤。
本书还包含有效的捕获方法,无需安装 Wireshark 即可直接用于生产。
Wireshark 是一款出色的故障排除和学习工具,在本书的范围内,我们为不同类型的受众(如网络管理员、安全审计员、协议学习者和故障排除人员)选择了最佳用例。
这本书涵盖了什么
第 1 章、数据包分析器,涵盖了数据包分析器的定义及其使用案例、网络接口命名约定、pcap/pcanpng 文件扩展名以及网络分析器工具的类型。
第 2 章、捕获数据包,讲述如何使用 Wireshark、tcpdump 和 snoop 捕获数据包;如何使用 Wireshark 显示过滤器;以及如何使用 Wireshark 的酷炫功能,如 Decode-As 和协议首选项。此外,我们还将介绍 TCP 流、导出图像、生成防火墙 ACL 规则、自动捕获设置和名称解析功能。
第 3 章、分析 TCP 网络,涵盖 TCP 状态机、TCP 连接建立和关闭序列、实际故障排除实验,如(CLOSE_WAIT、TIME_WAIT)、如何识别和修复延迟问题,以及 Wireshark TCP 序列分析标志(零窗口、dup-ok、TCP 重新传输和窗口更新)功能。
第四章,解析 SSL/TLS ,涵盖了使用 Wireshark 的 TLS/SSL 双向相互认证过程,使用 Wireshark 的 SSL/TLS 解密,以及使用 Wireshark 的握手失败识别。
第 5 章,分析应用层协议,讲述如何使用 Wireshark 显示过滤器分析协议,这些协议如何工作,如何使用 tcpdump/Wireshark 模拟、捕获和显示这些数据包。
第 6 章、 WLAN 捕获,涵盖了 WLAN 捕获设置和监控模式、使用 tcpdump 捕获、802.11 显示过滤器、第 2 层数据报帧类型、Wireshark 显示过滤器以及其他可用的 Wi-Fi 嗅探产品。
第 7 章、安全分析,涵盖 Wireshark 的安全方面,并讨论使用案例,如 Heartbleed bug、SYN flood/缓解、ICMP flood/缓解、MITM、BitTorrent 和主机扫描。
这本书你需要什么
本书涵盖的主题要求对 TCP/IP 有基本的了解。本书中使用的例子独立于操作系统。所有的例子都是在 MAC 和 Linux 操作系统中执行的。Windows 用户可以安装 Cygwin 来使用 Linux 命令行实用工具。本书中使用了以下可执行文件:
- Wireshark
- tcpdump
- 窥探
- 挖苦
- 网络管理命令行工具
- Java 语言(一种计算机语言,尤用于创建网站)
- wget
- dhclient
- nmap
这本书是给谁的
这本书提供了背景信息,以帮助读者理解所讨论的主题。本书的目标读者包括:
- 网络/系统管理员
- 安全顾问和 IT 官员
- 架构师/协议开发人员
- 白帽黑客
习俗
在这本书里,你会发现许多区分不同种类信息的文本样式。下面是这些风格的一些例子和它们的含义的解释。
文本中的码字、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 句柄如下所示:“通过单击 Wireshark 图标或在命令行中键入Wireshark
来启动 Wireshark。”
任何命令行输入或输出都按如下方式编写:
[bash ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout 60
新术语和重要词汇以粗体显示。你在屏幕上看到的词,比如在菜单或者对话框中,出现在文本中是这样的:“点击界面列表;Wireshark 将显示系统中可用网络接口的列表。
注意
警告或重要提示出现在这样的框中。
Tip
提示和技巧是这样出现的。
读者反馈
我们随时欢迎读者的反馈。让我们知道你对这本书的看法——你喜欢或不喜欢什么。读者的反馈对我们来说很重要,因为它有助于我们开发出真正让你受益匪浅的图书。
要给我们发送总体反馈,只需发送电子邮件<[feedback@packtpub.com](mailto:feedback@packtpub.com)>
,并在邮件主题中提及书名。
如果有一个你擅长的主题,并且你有兴趣写一本书或者为一本书投稿,请查看我们在www.packtpub.com/authors的作者指南。
客户支持
既然您已经是 Packt book 的骄傲拥有者,我们有许多东西可以帮助您从购买中获得最大收益。
下载示例代码
您可以从您在http://www.packtpub.com的账户下载您购买的所有 Packt Publishing 书籍的示例代码文件。如果你在其他地方购买了这本书,你可以访问 http://www.packtpub.com/support 的并注册,让文件直接通过电子邮件发送给你。
勘误表
尽管我们已尽一切努力确保内容的准确性,但错误还是会发生。如果您在我们的某本书中发现了错误——可能是文本或代码中的错误——如果您能向我们报告,我们将不胜感激。这样做,你可以让其他读者免受挫折,并帮助我们改进本书的后续版本。如果您发现任何勘误表,请通过访问http://www.packtpub.com/submit-errata,选择您的图书,点击勘误表提交表链接,并输入您的勘误表的详细信息。一旦您的勘误表得到验证,您的提交将被接受,该勘误表将被上传到我们的网站或添加到该标题的勘误表部分下的任何现有勘误表列表中。
要查看之前提交的勘误表,请前往https://www.packtpub.com/books/content/support并在搜索栏中输入图书名称。所需信息将出现在勘误表部分。
盗版
互联网上版权材料的盗版是所有媒体都存在的问题。在 Packt,我们非常重视版权和许可证的保护。如果您在互联网上发现我们作品的任何形式的非法拷贝,请立即向我们提供地址或网站名称,以便我们采取补救措施。
请通过<[copyright@packtpub.com](mailto:copyright@packtpub.com)>
联系我们,并提供可疑盗版材料的链接。
我们感谢您帮助保护我们的作者,以及我们为您带来有价值内容的能力。
问题
如果您对本书的任何方面有问题,可以通过<[questions@packtpub.com](mailto:questions@packtpub.com)>
联系我们,我们将尽最大努力解决问题。
一、数据包分析器
数据包分析器也称为数据包嗅探器或网络协议分析器。Packet analyzer 能够从有线、无线、蓝牙、VLAN、PPP 和其他网络类型中获取原始数据包,而无需应用进行处理。通过这样做,它把整个科学和创新带到了这个领域。在本章中,我们将通过讨论以下主题来了解数据包分析器的一些使用案例:
- 数据包分析器的用途
- Wireshark 简介
- 其他数据包分析器工具
- 移动数据包捕获
数据包分析器的用途
更实际的是,数据包分析器用于网络安全和分析原始流量,以便检测扫描和攻击,并用于嗅探、网络故障排除和许多其他用途,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00002.jpeg
数据包分析器可按如下方式使用:
- 网络管理员可以诊断网络上的问题
- 安全架构师可以对数据包执行安全审计
- 协议开发者可以诊断/学习协议相关的问题
- 白帽黑客可以发现应用中的漏洞,并在黑帽黑客发现之前修复它们
使用不仅限于这些要点,在这个领域有许多新的工具和创新。找到一个用例,构建自己的包分析器;最好的例子就是 Wireshark。
【Wireshark 简介
Wireshark 可能是当今最好的开源数据包分析器之一。Wireshark 是一款功能强大的数据包分析工具,具有易于使用、丰富的 GUI 和命令行实用工具,并有非常活跃的社区支持:【http://ask.wireshark.org】。
Wireshark 使用pcap
( libpcap
)来捕获数据包,这意味着它可以在离线模式下捕获数据包(查看捕获的数据包)和在线模式(实时流量)下捕获流量并在 Wireshark GUI 中显示。打开后,Wireshark GUI 如下所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00003.jpeg
Wireshark 功能
我们将在下图中看到 Wireshark 中的一些重要功能:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00004.jpeg
Wireshark 具有以下很酷的内置功能,下面列出了其中一些:
- 在 UNIX 和 Windows 中都可用
- 从各种类型的接口捕获实时数据包的能力
- 使用多种标准过滤数据包
- 能够解码更大的协议集
- 可以保存和合并捕获的数据包
- 可以创建各种统计数据
- 用户友好的 GUI 和命令行界面
- 积极的社区支持(http://ask.wireshark.org)
Wireshark 的 dumpcap 和 tshark
Wireshark 安装提供了一些命令行工具,如 dumpcap
和tshark
。Wireshark 和tshark
依靠dumpcap
抓取流量;更高级的功能由tshark
完成。另请注意,dumpcap
可以作为它自己的独立实用工具运行。tshark
是 Wireshark 的命令行版本,可用于远程终端。
Wireshark 数据包捕获流程
用户必须知道 Wireshark 安装在哪里,并且在开始捕获分接头 ( 测试 接入点)或交换机端口分析器 ( SPAN ) 端口之前,必须遵守贵组织的政策。
通常,开发人员在他们的个人笔记本电脑/台式机上安装 Wireshark,并捕获从机器进出的数据包。
为此,应遵循某些指南:
-
确保你被允许做你要做的事情;在捕获数据包之前,请检查您的公司策略。
-
操作系统必须支持包捕获:
- 内核默认启用 Linux 包套接字支持
- Windows 要求安装
WinPCap
-
选择接口并在其上启用混杂模式。混杂模式接受所有数据包,无论它们是否发往该接口。
-
如果使用 Wi-Fi 接口,请启用无线局域网捕获的监控模式。
-
Start capturing and use Wireshark’s different features like (filters/statistics/IO/save) for further analysishttps://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00005.jpeg
其他数据包分析工具
Wireshark 是一款数据包分析工具,使用诸如数据包编辑/重放、执行 MITM、ARP 欺骗、IDS 和 HTTP 代理等功能,还有其他可用的数据包分析工具也可以使用。
以下是市场上著名的数据包分析器工具列表(不限于此);许多其他产品也可以买到。下表列出了工具及其功能:
|
工具
|
数据包编辑
|
数据包重放
|
ARPspoof/MITM
|
密码嗅探
|
入侵检测
|
HTTP 调试器
|
| — | — | — | — | — | — | — |
| 连线编辑(https://wireedit.com/) | Y | N | 普通 | 普通 | 普通 | 普通 |
| 斯卡帕(http://www.secdev.org/) | Y | Y | Y | Y | 普通 | Y |
| ettcap(https://ettcap . github . io/ettcap/ | Y | 普通 | Y | Y | 普通 | 普通 |
| tcpreplay(http://tcpreplay.synfin.net/) | 普通 | Y | 普通 | 普通 | 普通 | 普通 |
| 钻头扭转(http://bittwist.sourceforge.net/ | Y | 普通 | 普通 | 普通 | 普通 | 普通 |
| 凯恩(http://www.oxid.it/cain.html) | 普通 | 普通 | Y | Y | 普通 | 普通 |
| 放风(https://www.snort.org/) | 普通 | 普通 | 普通 | 普通 | Y | 普通 |
移动数据包捕获
Wireshark 在 Android、iOS 或 Windows 等移动平台上不可用。为了捕获移动流量,基于该平台建议使用以下工具:
|
平台
|
使用的数据包捕获工具
|
统一资源定位器
|
| — | — | — |
| Windows 操作系统 | 微软网络分析仪 | http://www.microsoft.com/en-in/download/details.aspx?id=19484 |
| ios | 帕罗斯岛 | http://sourceforge.net/projects/paros/ |
| 机器人 | 鲨鱼为根 | http://www.appbrain.com/app/shark-for-root/lv.n3o.shark |
| Kismet 安卓 PCAP | http://www.kismetwireless.net/android-pcap/ |
使用 Wireshark,还可以使用各种其他技术来捕获移动流量。其中一种技术是在笔记本电脑上创建一个 Wi-Fi 热点,允许手机使用这个 Wi-Fi,并使用 Wireshark 嗅探 Wi-Fi 接口上的流量。
总结
在本章中,我们学习了什么是数据包分析器及其使用案例。在简要介绍 Wireshark 之后,我们讨论了 Wireshark 捕获数据包时的幕后操作;Wireshark 的优势和重要功能;捕获数据包之前的必要先决条件;以及用于数据包编辑/嗅探/重放等的其他数据包分析器工具。我们还提供了移动数据包捕获的简要概述。
下一章将更具体地介绍 Wireshark 及其技巧和窍门。之后,我们将探讨 TCP 故障排除,然后深入研究 SSL 和其他应用协议,如 DHCPv6、DHCP、DNS 和 HTTP。我们还将分析 Wi-Fi 捕获,并在 Wireshark 和tcpdump
的帮助下进行一些安全性分析。
二、捕获数据包
在前一章中,我们学习了数据包分析器的用途。在本章中,我们将了解更多关于 Wireshark GUI 功能的信息,并通过以下主题了解它如何帮助有效地捕获和分析数据包:
- 使用 Wireshark 接口列表捕获数据包
- 使用 Wireshark 启动选项捕获数据包
- 捕获选项
- Wireshark 过滤器示例
- Wireshark 数据包列表窗格
- Wireshark 数据包详细信息窗格
- Wireshark 功能
- tcpdump 和 snoop 示例
数据包捕获指南
通过单击 Wireshark 图标或在命令行中键入Wireshark
来启动 Wireshark 。Wireshark 启动时会启动以下屏幕,并提供以下捕获数据包的方法:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00006.jpeg
下表解释了我们在开始屏幕上的各种选项:
|
没有。
|
Wireshark 捕获选项
|
这是什么?
|
| — | — | — |
| one | 接口列表 | 打开捕获接口的实时列表,并对传入/传出数据包进行计数 |
| Two | 开始 | 您可以从列表中选择一个接口并开始捕获数据包 |
| three | 捕获选项 | 提供用于捕获和显示数据包的各种选项 |
| four | 打开最近的 | Wireshark 显示最近使用的数据包 |
我们将逐一详细介绍每个捕获选项。
用接口列表捕获数据包
点击界面列表;Wireshark 将通过显示进出接口的数据包,显示系统中可用网络接口的列表以及哪个处于活动状态,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00007.jpeg
选择右侧(活动)接口,点击开始按钮开始捕获数据包。如果要在回环(127.0.0.1
)上捕获数据包,选择接口 lo0 。
常用接口名称
接口名告诉你网络类型;通过查看接口名称,用户应该了解捕获设置与哪个网络相关联,例如,eth0
代表Ethernet
。下图显示了其中的一些:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00008.jpeg
捕获带有开始选项的数据包
在开始选项中,用户可以多选或选择列表中显示的界面,然后点击开始。这不能让您灵活地查看数据包在哪个接口上是活动的。用户可以通过双击界面或者点击捕获选项来配置捕获选项:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00009.jpeg
使用捕获选项捕获数据包
Wireshark 可以灵活地配置需要用各种捕获选项捕获的数据包。首先,尝试这些基本的设置:
-
选择数据包进出的实时接口。
-
点击捕获选项,Wireshark 将打开捕获选项对话框。
-
启用混杂模式,这将允许网络接口接收所有数据包。
-
检查快照长度大小。此选项将告诉您 Wireshark 应该捕获的每帧数据的大小;这在捕获报头帧或保持数据包较小时非常有用。
-
名称解析尝试将数字地址(例如,MAC 地址、IP 地址和端口)解析为其对应的名称,该类别下定义了以下选项:
- 解析 MAC 地址:该选项用于将 MAC 地址转换为人类可读的格式;例如
28:cf:e9:1e:df:a9
将翻译成192.168.1.101
。 - 解析网络层名称 (IP 名称解析):用于将 IP 地址转换为其对应的主机名(例如,
216.58.220.46
将翻译为google.com
)。 - 解析传输层名称 (TCP/UDP 端口名称解析):用于将众所周知的端口转换为人类可读的格式(例如,
443
将翻译为https
)。
- 解析 MAC 地址:该选项用于将 MAC 地址转换为人类可读的格式;例如
-
使用外部网络名称解析器对每个唯一的 IP 地址执行反向 DNS 查找(例如
216.58.196.14
将转换为ns4.google.com
),也称为反向 DNS 查找。
用户也可以通过选择 Wireshark 视图菜单并应用以下设置来选择这些选项:
- 查看|名称解析|使用外部网络名称解析器
- 查看|名称解析|为 MAC 层启用
- 查看|名称解析|启用传输层
- 查看|名称解析|启用网络层
名称解析的缺点如下:
- 启用这些名称解析选项后,如果流量很大并且有大量唯一的 IP 地址,Wireshark 将生成额外的数据包来解析来自名称服务器的名称。使用这些设置,Wireshark 会变得非常慢。
- Wireshark 缓存解析的 DNS 名称,因此如果名称服务器信息改变,需要手动重新加载。
捕获过滤器选项
Wireshark 为提供了一系列捕获过滤器选项,使用这些选项来决定将哪些数据包保存到磁盘。在较长时间内捕获数据包时,这些选项非常有用。Wireshark 为此使用了 Berkeley 包过滤 ( BPF )语法,例如tcp src port 22
。这个选项也节省了磁盘空间。例如,要仅捕获 TCP 数据包,请遵循给定的步骤:
- 点击捕获选项。对话框将打开,如屏幕截图所示。
- 选择活动接口,将混杂模式设置为启用或禁用。
- Click on Capture Filter. Once the dialog box appears, choose the TCP only filter and click on OK.https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00010.jpeg
- 点击开始按钮,开始捕获 TCP 数据包。
定期自动捕获文件
用户可以微调 Wireshark 来定期自动捕获文件。为此,点击捕获选项 | 捕获文件,如以下截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00011.jpeg
Wireshark 会生成test_00001_20150623001728.pcap
和test_00002_20150623001818.pcap
等文件。
多个生成文件的格式如下:
test
:这是文件名00001
:这是文件编号- 这是日期/时间戳
pcap
:这是文件扩展名
故障排除
如果数据包没有出现在 Wireshark 主窗口中,请执行以下操作:
- 检查正确的网络接口;确保有实时流量
- 尝试关闭/打开混杂模式
如果没有出现可以执行捕获的接口,请执行以下操作:
- 检查 Wireshark 是否有足够的权限使用网卡来捕获数据
- 从http://wiki.wireshark.org/CaptureSetup/CapturePrivileges验证捕获权限
注意
如果问题没有得到解决,你还可以使用 https://ask.wireshark.org/的 Wireshark 社区。
Wireshark 用户界面
当 Wireshark 开始捕获数据包时,或者当打开一个.pcap
文件进行离线查看时,会出现 Wireshark 主窗口。它看起来类似于下面的截图:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00012.jpeg
Wireshark UI 界面由不同的窗格组成,并为用户提供各种选项进行自定义。在本章中,我们将详细介绍这些窗格:
|
项目
|
这是什么?
|
| — | — |
| 红色的盒子 | 这表明 Wireshark 正在运行并捕获数据包 |
| one | 这是过滤器工具栏,用于根据应用的过滤器过滤数据包 |
| Two | 这是数据包列表窗格,显示所有捕获的数据包 |
| three | 这是数据包详细信息窗格,以详细的形式显示选定的数据包 |
| four | 这是数据包字节窗格,以十六进制转储格式显示选定的数据包 |
首先,只需观察屏幕中的窗格2;显示的数据包以不同的颜色出现。这是 Wireshark 最好的特性之一;它根据设置的过滤器对数据包进行着色,并帮助您可视化您正在寻找的数据包。
要管理(查看、编辑或创建)着色规则,请前往查看 | 着色规则。Wireshark 会显示着色规则对话框,如截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00013.jpeg
用户可以通过点击 New 按钮,选择过滤器名称和过滤器字符串,然后应用前景色和背景色来创建新的规则,用特定的颜色定制数据包。
过滤工具栏
Wireshark 显示过滤器显示数据包及其可用的颜色选项。Wireshark 显示过滤器通过提供所有数据包的完整剖析来改变捕获文件的视图,这有助于高效地分析网络跟踪文件。例如,如果用户只对 HTTP 数据包感兴趣,用户可以将显示过滤器设置为http
,如下一个截图所示。
应用显示过滤器的步骤如下:
- 打开
http_01.pcap
文件。 - 在过滤区输入
http
协议,点击应用。
一旦应用了过滤器,数据包列表窗格将只显示与 HTTP 协议相关的数据包:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00014.jpeg
Wireshark 显示过滤器可以从数据包列表窗格中显示的列应用或准备,方法是选择该列,然后右键单击并转到应用为过滤器 | 选定的(如下图所示)以从源 IP 地址122.167.102.21
创建过滤器:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00015.jpeg
Wireshark 为提供了从细节窗格应用过滤器的灵活性;步骤保持不变。
Wireshark 还提供清除过滤器的选项。为此,点击清除(在过滤器工具栏中可用)以显示整个捕获的数据包。
过滤技术
正确捕获和显示数据包将有助于您捕获数据包。例如,要跟踪在两个主机:HOSTA
( 10.0.0.221
)和HOSTB
( 122.167.99.148
)之间交换的数据包,打开SampleCapture01.pcap
文件并应用过滤器ip.src == 10.0.0.221
,如下所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00016.jpeg
让我们看看突出显示的部分描述了什么:
|
项目
|
描述
|
| — | — |
| one | 应用过滤器ip.src == 10.0.0.221
。 |
| Two | 数据包列表窗格显示从源到目的地的流量。源码显示不变的 IP 地址10.0.0.221
。没有证据表明哪个数据包是从主机122.167.99.148
发送到主机10.0.0.221
的。 |
现在将过滤器(ip.src == 10.0.0.221) && (ip.dst == 122.167.99.148)
修改为(ip.src == 10.0.0.221) or (ip.dst == 122.167.99.148)
。这将给出如下屏幕截图所示的结果:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00017.jpeg
前面截图中的高亮部分解释如下:
|
项目
|
描述
|
| — | — |
| one | 应用的过滤器(ip.src == 10.0.0.221) && (ip.dst == 122.167.99.148)
|
| Two | 源 IP 地址(10.0.0.221
)不变 |
| three | 目的地 IP 地址(122.167.99.148
)不变 |
同样,数据包列表窗格不显示两台主机之间的对话。
现在修改过滤器ip.addr == 122.167.99.148
。ip.addr
字段将匹配源地址和目的地址的 IP 报头,并显示主机之间的对话。请记住选择如下所示的目的 IP 地址:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00018.jpeg
让我们看看突出显示的部分描述了什么:
|
项目
|
描述
|
| — | — |
| one | 应用的过滤器ip.addr == 122.167.99.148
|
| Two | 源 IP 不是常数;它显示了两台主机之间的对话 |
| three | 目标 IP 不是常数;它显示了两台主机之间的对话 |
通过使用显示过滤器eth.addr == 06:73:7a:4c:2f:85
选择目的 MAC 地址来捕获相同的对话。
过滤器示例
一些常见的过滤器示例如下:
|
过滤器/采集名称
|
过滤阀
|
| — | — |
| 给定端口上的数据包 | tcp.port == 443
|
| 源端口上的数据包 | tcp.srcport=2222
|
| 端口443
上的 SYN 数据包 | (tcp.port == 443) && (tcp.flags == 0x0010)
|
| HTTP 协议 | http
|
| 基于 HTTP get
方法 | http.request.method == "GET"
|
| 使用&&
、tcp
和http
| tcp && http
|
| 检查tcp
窗口大小 | tcp.window_size <2000
|
| 没有Arp
用于正常流量 | !arp
|
| MAC 地址过滤器 | eth.dst == 06:43:7b:4c:4f:85
|
| 过滤掉 TCP 确认 | tcp.flags.ack==0
|
| 仅检查 RST 和 ACK 数据包 | (tcp.flags.ack == 1) && (tcp.flags.reset == 1)
|
| 过滤所有 SNMP | Snmp
|
| HTTP 或 DNS 或 SSL | http || dns | ssl
|
不需要记忆过滤器;有一个简单的方法来应用它。显示过滤器自动完成功能列出了第一个句点".
"之后所有已添加到显示过滤器的解剖器,如以下屏幕截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00019.jpeg
注意
值得查看以下链接,了解完整的显示过滤器参考:
- 查看 TCP 显示过滤器参考:https://www.wireshark.org/docs/dfref/t/tcp.html
- 检查这个替代协议显示过滤器参考:https://www.wireshark.org/docs/dfref/
数据包列表窗格
数据包列表窗格显示来自.pcap
(或接受的 Wireshark 扩展)文件或来自实时捕获的数据包,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00020.jpeg
让我们讨论显示的字段:
|
项目
|
这是什么?
|
| — | — |
| https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00021.jpeg | 显示不同的数据包;每一行对应于一个称为帧的不同数据包 |
| 1.号码 | 当前实时/离线捕获中的数据包数量 |
| 2.时间 | 显示数据包被捕获时的时间戳信息libpcap
文件的自动设置为微秒;所有数据包都将被捕获,时间以微秒计,如下一个截图所示 |
| 3.来源 | 数据包来源的 IP 地址 |
| 4.目的地 | 数据包结束的目的 IP 地址 |
| 5.草案 | Wireshark 将根据标准端口显示有关数据包协议的信息 |
| 6.长度 | 以字节表示的数据包长度 |
| 7.信息 | 显示数据包的概要以及数据包的性质 |
要更改数据包的时间戳信息,请进入查看 | 时间显示格式查看可用的显示格式,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00022.jpeg
Wireshark 设置时间参考功能使您能够查看来自所选数据包的时间参考。打开捕获文件http.pcap
,设置数据包 38 中的时间基准。为此,选择 packet 38,右键单击,然后选择设置时间参考(toggle) ,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00023.jpeg
设置*REF*
后,它将成为所有后续数据包时间计算的起点,如下面截图中的所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00024.jpeg
数据包详细信息窗格
数据包详细信息窗格将以更详细的形式显示当前选择的数据包。在下面的截图中,选择了一个 HTTP 数据包,其详细信息显示在标有数字 1 到 5 的信息中。让我们看看这些是什么:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00025.jpeg
帧协议仅由 Wireshark 使用。所有的 TCP/IP 协议都基于此。该帧显示捕获数据包的时间,如以下屏幕截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00026.jpeg
以太网是 TCP/IP 协议栈中的链路层协议。它将网络数据包从发送主机发送到一台(单播)或多台(组播/广播)接收主机,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00027.jpeg
以太网中有用的过滤器有:
eth.dst == 06:3c:0f:39:2e:f7
:仅显示发送到此 MAC 地址的数据包eth.dst==ff:ff:ff:ff:ff:ff
:仅显示广播流量
下表描述了以太网帧的数据包结构:
|
序文
|
目标 MAC 地址
|
源 MAC 地址
|
类型/长度
|
用户数据
|
帧校验序列
|
| — | — | — | — | — | — |
| eight | six | six | TwoIPv4 的 0800IPv6 的 86DDARP 的 0806 | 46-1500 | four |
前同步码(8 字节)和 FCS (4 字节)不是帧的一部分,Wireshark 不会捕获该字段。
因此总的以太网报头是 14 字节——6 字节用于目的地址,6 字节用于源地址,2 字节用于以太网类型。
互联网协议信息涉及如何传送 IP 分组以及它是使用 IPv4 还是 IPv6 来传送数据报分组。
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00028.jpeg
前面的屏幕截图显示 IPv4 协议用于传递数据报数据包。IP 协议中有用的显示过滤器有:
ip.src == 122.166.88.120/24
显示来自子网的流量ip.addr==122.166.88.120
显示进出给定主机的流量- 主机
122.166.88.120
捕获/过滤来自主机的流量
TCP 协议数据包包含所有与 TCP 相关的协议数据。如果通过 UDP 进行通信,TCP 将被 UDP 取代,如下面的屏幕截图所示。Wireshark 将根据序列号进行 SEQ/确认分析,并将提供专家信息:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00029.jpeg
如果数据包包含任何应用协议,则显示<<APPLICATION-LAYER>>
协议。如下面的截图中的所示,选中的数据包 36 具有 HTTP 协议数据。Wireshark 能够根据标准端口解码协议,并以可读(RFC 定义的)格式在数据包详细信息窗格中显示此信息。
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00030.jpeg
在接下来的章节中,我们将更详细地讨论与应用相关的协议。
数据包字节窗格
数据包字节窗格显示帧中包含的字节,突出显示的区域设置为数据包细节窗格中选择的节点。
Wireshark 功能
Wireshark 加载了一些令人敬畏的特性。让我们看几个,虽然还有更多。
解码为
Decode-As 功能允许 Wireshark 根据所选协议对数据包进行解码。通常,Wireshark 会根据标准端口自动识别和解码传入的数据包,例如,端口443
将被解码为 SSL。如果服务在非标准端口上运行,例如 SSL 标准端口是443
而服务在4433
上运行,在这种情况下,Decode-As 功能可用于使用 SSL 协议首选项对该通信进行解码。
从打开样本https.pcap
文件。在 Wireshark 中打开该文件时,会捕获 HTTPS 流量。它不显示 SSL 相关的数据;相反,它只显示所有 TCP 通信:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00031.jpeg
要将此流量解码为 SSL,请执行以下步骤:
- Click on Analyze | Decode As:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00032.jpeg
- The Decode As popup will appear as shown in the following screenshot. Choose the protocol (SSL in this example) that is required for decoding the given traffic:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00033.jpeg
- The SSL traffic protocol is shown in Wireshark:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00034.jpeg
注意
SSL 解码并不意味着它已经解密了 SSL 数据。
协议首选项
协议首选项功能为您提供了定制 Wireshark 显示处理方式和数据包分析方式的灵活性。您可以通过以下方法之一设置协议首选项:
- 进入编辑 | 偏好设置 | 协议调整设置
- 一个简单的方法是右键单击数据包细节窗格中的协议,并选择协议首选项
Wireshark 支持大量协议及其首选项,例如 HTTP 协议首选项及其在下表中定义的含义:
|
HTTP 协议首选项
|
这是什么意思?
|
| — | — |
| 重组跨越多个 TCP 段的 HTTP 头 | 如果 HTTP 头通过多个 TCP 段传输,HTTP 解析器将重新组装 HTTP 头 |
| 重组跨越多个 TCP 段的 HTTP 主体 | 如果 HTTP 主体通过多个 TCP 段传输,HTTP 解析器将重新组装它 |
| 重新组装分块的传输编码几何体 | 重新组装跨段的所有块,并将它们添加到有效载荷中 |
| 解压缩实体主体 | 用于压缩数据的可视化(.gzip
或编码) |
| SSL/TLS 端口 | 添加/删除 SSL/TLS 端口(默认为443
) |
| 自定义 HTTP 头字段 | 定义新的标题字段 |
以下屏幕截图显示了 Wireshark 中的 HTTP 协议首选项:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00035.jpeg
Tip
参考第 05 章、中查找 top HTTP 响应时间的例子分析使用协议首选项时 DHCP、DHCPv6、DNS、HTTP 协议。
IO 图
使用 IO 图检查客户端和服务器交互数据进行有意义的分析。Wireshark IO 图测量吞吐量(速率为每滴答一个数据包),其中每滴答为一秒。在本例中,我们将了解如何利用 IO 图。在 Wireshark 中打开文件http_01.pcap
,并按照给定的步骤操作:
-
点击统计 | IO 图。
-
将出现 IO 图形对话框。
-
在 IO 图形对话框中,尝试找到尖峰并点击它。
-
当您单击图表(高位区域)时,Wireshark 会自动在数据包列表窗格中显示相应的数据包。
注意
在给定的例子中,有许多重复的 ack .
-
返回到 IO 图形对话框。
-
选择图表 2 并输入
tcp.analysis.duplicate_ack
。 -
点击图表 2 应用过滤器。
-
IO 图对话框将显示重复 ACK 的吞吐量。
IO 图有很多用例。其中一些如下:
- 使用 IO 图分析流量模式,例如通过在协议上绘制图表来分析流量如何分布,例如
tcp
、http
、udp
、ntp
和ldap
。 - 执行安全分析时,IO 图会派上用场。IO 图的更多例子可以在第 07 章、网络安全分析中找到。
以下屏幕截图显示了前面步骤的结果:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00036.jpeg
跟随 TCP 流
TCP 流特性允许用户查看来自 TCP 流的数据。在 Wireshark 中打开文件http_01.pcap
,按照 TCP 流获取第一个 HTTP OK,如图所示:
在本例中,我们在数据包#35 上找到 HTTP OK,然后右键单击并选择跟随 TCP 流:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00037.jpeg
一旦应用了流,一个 TCP 流对话框将打开,显示在这个 HTTP 对话中发送了哪个请求和接收了什么响应:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00038.jpeg
流内容有六种格式,如图所示;截图中的红色内容是请求,截图中的蓝色内容是响应:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00039.jpeg
导出显示的数据包
导出指定数据包功能允许您在不同的文件中导出过滤后的数据包。比如在 Wireshark 中打开http.pcap
,导出 HTTP OK 包。导出指定数据包的步骤如下:
- Apply the filter
http.response.code == 200
in the Filter bar:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00040.jpeg - Go to File | Export Specified Packets. This opens up the dialog box with the export options, as shown:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00041.jpeg
生成防火墙 ACL 规则
使用 Wireshark,网络管理员可以为防火墙产品生成 ACL 规则,例如:
- 思科 IOS
- IP 过滤器(IP 过滤器)
- IP 防火墙(ipfw)
- 网络过滤器(iptables)
- 分组过滤器
- Windows 防火墙(netsh)
Tip
存在 MAC 地址和 IPv4 地址的规则;该筛选器支持 TCP、UDP 端口和 IPv4 端口组合。
在 Wireshark 中生成 ACL 规则的步骤如下:
- Go to Tool | Firewall ACL Rules:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00042.jpeg
- The Firewall ACL Rules dialog box will appear. Choose Product and Filter, specify the ACCEPT/DENY criteria, and a rule will be generated by Wireshark in this dialog box, as shown:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00043.jpeg
Tcpdump 和 snoop
在生产环境中,通常不会安装诸如 Wireshark 之类的数据包捕获工具。在这种情况下,可以使用缺省捕获工具,例如用于(Linux 系统)的tcpdump
和snoop
(Solaris 缺省);稍后,可以在 Wireshark 中使用捕获的文件进行分析:
snoop
:这个工具捕获并检查网络数据包,并在 Sun Microsystems CLI 上运行- 这个工具在网络上转储流量,可以在 Windows、OS X 和 Linux 上运行
例如,下表显示了如何检查来自接口的数据包:
|
描述
|
Solaris
|
Linux 操作系统
|
| — | — | — |
| 如何检查来自所有接口的数据包 | bash# snoop
| bash#tcpdump –nS
|
| 如何用主机名捕获 | bash# snoop hostname
| bash# tcpdump host hostname
|
| 如何将捕获的信息写入文件 | snoop -o filename
| bash# tcpdump -w filename
|
| 如何在host1
和host2
之间捕获数据包并保存到文件中 | snoop -o capture_file.pcap host1 host2
| tcpdump -w capture_file.pcap src host1 and dst host2
|
| 如何捕获详细输出到屏幕的流量 | snoop -v -d eth0``snoop -d eth0 -v port 80
| tcpdump -i eth0
非常冗长的tcpdump
选项:tcpdump -i eth0 -v port 80``tcpdump -i eth0 -vv port 80
|
| 如何设置快照长度 | snoop -s 500
| tcpdump -s 500
|
| 如何捕获所有字节 | snoop –s0
| tcpdump –s0
|
| 如何捕获 IPv6 流量 | snoop ip6
| tcpdump ip6
|
| 如何捕获协议 | snoop multicast``snoop broadcast``snoop bootp``snoop dhcp``snoop dhcp6``snoop pppoe``snoop ldap
| tcpdump -n "broadcast or multicast"``tcpdump udp``tcpdump tcp``tcpdump port 67``tcpdump port 546``tcpdump port 389
|
参考文献
您也可以参考以下链接,了解本章所涵盖主题的更多信息:
- https://www.wireshark.org/docs/wsug_html_chunked/
- https://wiki.wireshark.org/CaptureSetup/Ethernet
- https://goo.gl/vxI2jk
总结
在本章中,我们学习了如何使用 Wireshark GUI。然后我们探讨了什么是捕获过滤器和显示过滤器,如何设置捕获,牢记性能,以及如何在生产或远程捕获中利用其他捕获工具,如tcpdump
和snoop
。然后,我们了解了一些 Wireshark 功能,如 ACL 规则生成、IO 图、解码、导出数据包和协议首选项。
在下一章中,我们将学习 TCP 协议,并通过实验练习讨论其实际使用案例,这将有助于解决常见的网络问题(我们还将提供解决方案)。
三、分析 TCP 网络
TCP 旨在成为多种网络中常用的主机对主机协议。在本章中,我们将通过实验练习和例子详细分析 TCP 协议。
本章涵盖以下主题:
- 重述 TCP
- TCP 连接建立和清除
- TCP 故障排除
- TCP 延迟问题
- Wireshark TCP 序列分析
重述 TCP
传输 控制协议 ( TCP )最早定义于 RFC 675,v4 规范问世于 RFC 793。TCP 提供:
- 面向连接的 TCP 会话的建立和拆除
- 该服务发送和接收字节流,而不是消息,并保证接收的所有字节都与发送的字节相同,并且顺序正确
- 可靠的有序交付使用序列号来恢复被损坏、丢失、复制或由互联网通信系统无序交付的数据
- 流量控制防止接收方的缓冲空间溢出
- 拥塞控制(如 RFC 5681 中所定义的)算法有:慢启动、拥塞避免、快速重传和快速恢复
- 多路复用;每个 TCP 会话都有两个逻辑管道;进出管道
TCP 报头字段
每个 TCP 数据段都有一个 20 字节的报头和可选的数据值,如下图所示,在 Wireshark 数据包详细信息窗格中显示了一个 TCP 帧:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00044.jpeg
下表描述了标题字段和 Wireshark 过滤器及其说明:
|
TCP 报头
|
Wireshark 过滤器名称
|
描述
|
| — | — | — |
| 源端口(16 位) | tcp.srcport
| 发送者端口 |
| 目的端口(16 位) | tcp.dstport
| 接收器端口 |
| 序列号(32 位) | tcp.seq
| 定义 ISN 并控制 TCP 的状态 |
| 确认号(32 位) | tcp.ack
| ACK 包含主机想要接收的下一个 SEQNo |
| 标志(9 位) | | tcp.flags
| 控制位 |
| 内向的; 寡言少语的; 矜持的 | tcp.flags.res
| 供将来使用 |
| 目前 | tcp.flags.ns
| 实验的 |
| 连续焊接轨 | tcp.flags.cwr
| 拥塞窗口减少 |
| 电子通信网络 | tcp.flags.ecn
| 回声报 |
| 急迫的 | tcp.flags.urg
| 设置紧急指针字段 |
| 确认 | tcp.flags.ack
| 确认已设置 |
| 推 | tcp.flags.push
| 推送数据 |
| 重置 | tcp.flags.reset
| 重置连接 |
| synchronizing 同步 | tcp.flags.syn
| 同步序列号 |
| 鳍状物 | tcp.flags.fin
| 没有更多数据 |
| 窗口大小(16 位) | tcp.window_size
| 用于在三次握手中通告窗口大小 |
| Checksum (16 bits) | tcp.checksum
| 错误检查 |
| 紧急指针(16 位) | tcp.urgent_pointer
| 通知接收者该段中的一些数据是紧急的(序列号< =紧急消息< =序列号+紧急指针) |
| 可被 32 整除的选项(0-132 位) | tcp.options
| 选项,如最大段大小、无操作 ( NOP )、窗口比例、时间戳、SACK 允许 |
TCP 状态
连接在其生命周期中经历一系列状态。这些状态是:
|
TCP 状态
|
描述
|
| — | — |
| 听 | 服务器对传入连接开放。 |
| 同步发送 | 客户端已经启动了连接。 |
| 同步接收 | 服务器已收到连接请求。 |
| 确定的 | 客户端和服务器已经准备好进行数据传输,连接已经建立。 |
| 鳍-等待-1 | 客户端或服务器已经关闭了套接字。在 Linux 中,默认值是 60 毫秒:
[bash ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
|
| 鳍-等待-2 | 客户端或服务器已释放连接。在 Linux 中,默认值是 60 毫秒:
[bash ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
|
| 关闭-等待 | 客户端或服务器没有关闭套接字。CLOSE_WAIT
状态不会过期。 |
| 最后确认 | 等待来自客户端的待定确认。这是 TCP 与客户端对话的最后阶段。 |
| 时间-等待 | TIME_WAIT
表示本地应用关闭了连接,对方确认并发送了自己的 FIN。在 Linux 中,默认值是 60 毫秒:
[bash ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
|
| 关闭的 | 虚构的国家 |
注意
这个套接字命令行实用工具可用于监控网络连接及其状态:
[bash ~]ss -nt4 state CLOSE-WAIT
[bash ~]ss -nt4 state ESTABLISHED
[bash ~]netstat -an | grep CLOSE-WAIT
[bash ~]netstat -an | grep ESTABLISHED
TCP 连接建立和清除
在这一节中,我们将学习 TCP 如何打开和关闭它的连接。为了建立连接,使用三次握手过程,如下节所述。
TCP 三次握手
三次握手是从客户端套接字到服务器套接字的连接建立过程,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00045.jpeg
在 TCP 三次握手的开始之前,客户端将处于CLOSED
状态,服务器将处于LISTEN
状态,如图所示:
| 序列号 | TCP-A(122.167.84.137)状态 | 流量 CTL | TCP-B (10.0.0.221)状态 |
| 来自 | 至 | 来自 | 至 |
| one | 关闭的 | | | 关闭的 | 听 |
TCP 状态机
要在 Wireshark 中检查三次握手,请打开书中提供的normal-connection.pcap
文件。
握手信息–第一步[SYN]
握手过程的第一步是套接字客户机将构造一个 SYN 包,并将其发送给服务器。在此过程中,套接字客户端将执行以下任务:
tcp.flags.syn
被设置为1
,其 SYN 包由客户端发送。- 客户端生成并设置
tcp.seq=3613047129
初始序列号 ( 不是)。Wireshark 默认显示相对序列号;用户可以在编辑 | 首选项 | 协议 | TCP |相对序列号下更改此设置。 - 客户端设置
tcp.ack =0
。 tcp.window_size
被通告给服务器,它的值在包tcp.window_size_value == 65535,
中,包tcp.window_size_value == 65535,
告诉服务器它可以根据 MSS 传输多达65535
字节的数据。例如,如果 MSS 是 1440 字节,则客户端可以传输 45 个数据段。- TCP 客户端包括其他
tcp.options
如最大段尺寸 ( MSS )、无操作 ( NOP )、窗口规模、时间戳、SACK 允许。 - 客户端在“选择性确认”处理中选择
tcp.options.sack_perm == 1
。 - TSval/TSecr 是时间戳
tcp.options.timestamp.tsval == 123648340
。
下表描述了第一个握手消息的状态转换:
| Sr 号 | TCP-A(122.167.84.137)状态 | 流量 CTL | TCP-B (10.0.0.221)状态 |
| 来自 | 至 | 来自 | 至 |
| one | 关闭的 | | | 关闭的 | 听 |
| Two | 关闭的 | 同步发送 | | 听 | |
TCP 状态机更改同步发送
握手消息–第二步[SYN,ACK]
在这个过程中,服务器响应客户端的 SYN:
- 服务器设置
tcp.flags.syn =1
和tcp.flags.ack=1
,确认 SYN 已被接受。 - 服务器生成并设置 ISN
tcp.seq=2581725269
。 - 服务器将
tcp.ack=3613047130
设置为客户端tcp.seq+1
。 - 服务器将
tcp.window_size_value == 26847
设置为服务器窗口大小。 - 服务器设置
tcp.options
并响应客户端。
下表描述了第二握手消息的状态转换:
| Sr 号 | TCP-A(122.167.84.137)状态 | 流量 CTL | TCP-B (10.0.0.221)状态 |
| 来自 | 至 | 来自 | 至 |
| one | 关闭的 | | | 关闭的 | 听 |
| Two | 关闭的 | 同步发送 | | 听 | |
| three | 同步发送 | | | 听 | 同步接收 |
当服务器发送 SYN-RECEIVED 时,TCP 状态机发生变化
握手消息–第三步[ACK]
在成功交换该消息后,将在该连接中建立 TCP 连接:
- 客户端设置
tcp.flags.ack == 1
并发送给服务器。 - 客户端
tcp.seq=3613047130
是 ISN+1,tcp.ack=2581725270
是SYN_ACK( tcp.seq+1)
。 - 再次设置客户端窗口大小,这将由服务器
tcp.window_size_value == 4105
使用。
Tip
tcp.analysis.flags
向您显示包含来自 Wireshark 的某种专家消息的数据包。
下表描述了第三个握手消息的状态转换:
| Sr 号 | TCP-A(122.167.84.137)状态 | 流量 CTL | TCP-B (10.0.0.221)状态 |
| 来自 | 至 | 来自 | 至 |
| one | 关闭的 | | | 关闭的 | 听 |
| Two | 关闭的 | 同步发送 | | 听 | |
| three | 同步发送 | | | 听 | 同步接收 |
| four | 同步发送 | 确定的 | > | 同步接收 | 确定的 |
客户端发送 ACK 时的 TCP 状态机
TCP 数据通信
一旦建立了三向连接,数据就通过交换数据段进行通信,并且PUSH
标志被置位以指示数据作为八位字节流在连接上流动,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00046.jpeg
从normal-connection.pcap
文件中选择包#4 ,如下图所示;在数据包详细信息窗格中展开 TCP 部分:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00047.jpeg
正如您在前面的屏幕截图中看到的:
- 服务器正在向客户端发送数据包中显示的数据。
- 服务器设置
tcp.flags.push = 1
。 - 服务器设置
tcp.flags.ack =1
。 - 服务器数据为(29 字节),数据值为:
414e495348204e415448204e4f524d414c20434f4e4e4543...
。 - 服务器设置
(tcp.flags.ack == 1) && (tcp.flags.push == 1)
;也就是说,[PSH,ACK]
标志表示主机正在确认接收到一些先前的数据,并且还在发送一些更多的数据。
有用的 Wireshark 显示过滤器有:
data
: Displays the packet that contains the data information, for all IPs:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00048.jpegdata && ip.addr==10.0.0.221
:显示有数据并与给定 IP 地址交换的数据包列表tcp.flags.push == 1
:显示所有PUSH
数据包tcp.flags.push == 1 && ip.addr==10.0.0.221
:显示主机间的PUSH
数据包tcp.flags == 0x0018
:显示所有PSH, ACK
数据包tcp.flags == 0x0011
:显示所有FIN, ACK
数据包tcp.flags == 0x0010
:显示所有ACK
数据包
TCP 关闭序列
当客户端或服务器确定所有数据都已发送到接收方,我们可以关闭连接时,TCP normal close 出现。关闭 TCP 连接有三种方式:
- 客户端通过向服务器发送一个
FIN
包来开始关闭连接 - 服务器通过向客户端发送一个
FIN
包来开始关闭连接 - Both client and server initiate closing the connectionhttps://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00049.jpeg
打开normal-connection.pcap
文件,并在数据包列表窗格中选择数据包#5。进入 Wireshark 数据包详细信息窗格,如屏幕截图所示,检查 TCP 协议。
在 Wireshark 中,将序列号和确认号添加到列中。要添加序列号和确认号,选择 TCP 报头数据包,右键单击数据包详情中的字段(序列号 / 确认号)并选择显示为列。或者实现这些设置来添加新列:
- 进入编辑 | 首选项 | 栏目。然后添加一个新列,选择**“custom”:TCP . seq**。
- 进入编辑 | 首选项 | 栏目。然后添加一个新列,选择**“自定义”:tcp.ack** 。
服务器已经启动了FIN
数据包。数据传输完成后,请参见以下屏幕截图中的数据包#5:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00050.jpeg
正如您在前面的屏幕截图中看到的:
- 服务器启动
FIN
数据包以关闭数据包#5 中的连接 - 服务器设置
[FIN,ACK] (tcp.flags.fin == 1) && (tcp.flags.ack == 1)
并发送给客户端 - 服务器序列号
tcp.seq == 2581725299
在包#7 中得到确认 - 客户端正在启动
FIN
以关闭数据包#8 中的连接 - 客户端设置
[FIN,ACK] (tcp.flags.fin == 1) && (tcp.flags.ack == 1)
并发送给服务器 - 客户端序列号
tcp.seq == 3613047130
在数据包#9 中得到确认
TCP 状态机当服务器和客户端关闭 socket 连接时,服务器发起FIN
:
| Sr 号 | TCP-A(122.167.84.137)状态 | 流量 CTL | TCP-B (10.0.0.221)状态 |
| 来自 | 至 | 来自 | 至 |
| one | 关闭的 | | | 关闭的 | 听 |
| Two | 关闭的 | 同步发送 | | 听 | |
| three | 同步发送 | | | 听 | 同步接收 |
| four | 同步发送 | 确定的 | SEQ = 3613047130 > > | 同步接收 | 确定的 |
| five | 确定的 | 确定的 | > | 确定的 | 确定的 |
| six | 确定的 | 确定的 | > | 确定的 | 确定的 |
| seven | 确定的 | 确定的 | > | 确定的 | FIN_WAIT-1 |
| eight | 确定的 | 关闭 _ 等待 | > | FIN_WAIT-1 | FIN_WAIT-2 |
| nine | 关闭 _ 等待 | LAST_ACK | SEQ = 3613047130 > > | FIN_WAIT-2 | 时间 _ 等待 |
| Ten | LAST_ACK | 关闭的 | | 时间 _ 等待 | 关闭的 |
此场景中使用的 Wireshark 过滤器如下:
tcp.analysis:SEQ/ACK
:提供匹配序列号/确认号段的链接tcp.connection.fin
:提供专家信息tcp.flags == 0x0011
:显示所有的[FIN,ACK]
数据包
实验室练习
捕获普通 TCP 连接流的步骤(本书提供了一个示例程序)如下:
-
打开 Wireshark,开始捕获数据包,并选择显示过滤器
tcp.port==8082
。 -
使用
javac
命令编译 Java 程序TCPServer01.java
:bash$ ~ javac TCPServer01.java
-
使用
java
命令运行TCPServer01
:bash$ ~ java TCPServer01
-
验证服务器正在监听端口
8082
:bash$ ~ netstat -an | grep 8082 tcp46 0 0 *.8082 *.* LISTEN
-
使用
javac
命令编译客户端程序Client0301.java
:bash$ ~ javac Client0301.java
-
运行客户端程序:
bash$ ~ java Client0301
-
在 Wireshark 中查看和分析数据包。
TCP 故障排除
在本节中,我们将了解出现的各种网络问题,并尝试通过实验练习来分析和解决这些问题。先说Reset
( RST
)包。
TCP 复位序列
TCP RST
标志重置连接。它指示接收方应该删除该连接。接收器根据序列号和报头信息删除连接。如果接收者上不存在连接,则设置RST
,由于异常行为,它可以在 TCP 连接生命周期中的任何时间出现。让我们举一个例子:一个RST
包在收到SYN/ACK
后被发送,如下图所示。
SYN-ACK 后的 RST
在本例中,我们将了解为什么RST
被设置在SYN-ACK
之后,而不是ACK
:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00051.jpeg
在 Wireshark 中打开RST-01.pcap
文件:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00052.jpeg
如上图所示:
-
TCP
RST
数据包应该看不到 -
TCP
RST
在前两次握手完成后设置。一种可能的解释是:- 客户端连接从未存在过;通过 TCP 服务器发送原始数据包
- 客户端中止其连接
- 序列号被更改/伪造
席恩之后的 RST
这是最常见的用例。在 Wireshark 中打开RST-02-ServerSocket-CLOSED.pcap
文件。在本例中,服务器没有启动,客户端试图建立连接,连接拒绝了一个RST
数据包:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00053.jpeg
实验室练习
当服务器不处于监听状态时,在一般情况下生成RST
标志的步骤如下:
-
打开 Wireshark,开始捕获数据包,并选择显示过滤器
tcp.port==8082
。 -
编译客户端程序
Client0301.java
:bash$ ~ javac Client0301.java
-
运行客户端程序:
bash$ ~ java Client0301
-
在 Wireshark 中查看和分析
RST
数据包。
TCP 关闭 _ 等待
通常一个连接被卡在CLOSE_WAIT
状态。这种情况通常发生在接收方等待来自对等方的连接终止请求时。
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00054.jpeg
Tip
要找到处于CLOSE_WAIT
状态的套接字,使用以下命令:
bash:~ $ netstat -an | grep CLOSE_WAIT
tcp4 0 0 122.167.127.21.56294 10.0.0.21.9999 CLOSE_WAIT
要演示状态,请在 Wireshark 中打开close_wait.pcap
文件:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00055.jpeg
正如您在前面的屏幕截图中看到的:
- 服务器关闭套接字包#5,设置
tcp.flags.fin == 1
,并设置tcp.seq == 2131384057
。 - 客户端用数据包#7 中的
ACK
数据包tcp.ack == 2131384058
进行响应,并且没有关闭它的套接字,套接字保持在CLOSE_WAIT
状态。
CLOSE_WAIT
表示应用代码有问题,在高流量环境下,如果CLOSE_WAIT
持续增加,会使您的应用进程变慢,甚至崩溃。
实验室练习
再现CLOSE_WAIT
的步骤如下:
-
打开 Wireshark,开始捕获数据包,并选择显示过滤器
tcp.port==9999
。 -
使用
javac
命令编译 Java 程序Server0302.java
和Client0302.java
:bash$ ~ javac Server0302.java Client0302.java
-
使用
java
命令运行Server0302
:bash$ ~ java TCPServer01
-
验证服务器正在监听端口
9999
:bash $ netstat -an | grep 999 tcp46 0 0 *.9999 *.* LISTEN
-
运行客户端程序:
bash$ ~ java Client0302
-
检查 TCP 套接字的状态;它将处于
CLOSE_WAIT
状态:bash $ netstat -an | grep CLOSE_WAIT tcp4 0 0 127.0.0.1.56960 127.0.0.1.9999 CLOSE_WAIT
-
在 Wireshark 中分析数据包。
如何解析 TCP 关闭状态
步骤如下:
-
要删除
CLOSE_WAIT
,需要重新启动程序。 -
解决
CLOSE_WAIT
问题需要从客户端和服务器建立FIN
包。处理完记录后关闭客户端套接字和服务器套接字:socket.close(); à Initiates the FIN flow
-
打开
Client0302.java
文件,关闭套接字:Socket socket = new Socket(InetAddress.getByName("localhost"), 9999); … socket.close(); … Thread.sleep(Integer.MAX_VALUE);
-
编译并重新运行 Java 程序。
CLOSE_WAIT
将不可见。
TCP 时间 _ 等待
TIME_WAIT
状态的主要目的是当一端位于LAST_ACK
或CLOSING
重发FIN
并且一个或多个ACK
丢失时,优雅地关闭连接。
RFC 1122: " 当一个连接被主动关闭时,它必须在 TIME-WAIT 状态停留一段时间 2xMSL(最大段生存期)。但是,它可以接受来自远程 TCP 的新 SYN,以直接从时间等待状态重新打开连接,如果…
我们忽略条件,因为我们无论如何都处于TIME_WAIT
状态。
TCP 延迟问题
到目前为止,我们一直在排除与连接相关的问题。在本节中,我们将检查延迟部分。延迟可能出现在网络上,也可能出现在客户端或服务器的应用处理中。
潜伏的原因
识别延迟的来源在 TCP 故障排除中也起着重要的作用。让我们看看延迟的常见原因是什么:
- 可以使用
ping
实用工具测量网络慢速线路延迟 - 太多正在运行的进程会消耗内存。检查内存管理,使用 free,top 命令识别 CPU 和内存使用情况
- 应用启动时没有足够的内存或无法满足更多的请求
- 错误的 TCP 调整;验证
/etc/sysctl.cnf
文件 - 网络抖动;验证您的网络,并与网络管理员核实
- 编码差;通过在网络上执行负载测试来对您的代码进行基准测试
- 网关设置错误;检查网关,检验路由表,并检验网关
- 更高的跳数;执行跟踪路由并检查跳数(跳数越多,延迟增加越多)
- 网卡接口慢,接口宕机;检查网卡并验证其速度
识别潜伏期
各种网络实用工具可用于测量网络间的延迟,例如traceroute
、tcpping
和ping
。
-
ping
:该实用工具可用于测量往返时间 ( RTT ):bash$ ping -c4 google.com PING google.com (216.58.196.110): 56 data bytes 64 bytes from 216.58.196.110: icmp_seq=0 ttl=55 time=226.034 ms 64 bytes from 216.58.196.110: icmp_seq=1 ttl=55 time=207.748 ms 64 bytes from 216.58.196.110: icmp_seq=2 ttl=55 time=222.995 ms 64 bytes from 216.58.196.110: icmp_seq=3 ttl=55 time=162.507 ms --- google.com ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 162.507/204.821/226.034/25.394 ms
-
traceroute
:用于标识到达目的地的跳数——跳数越少,延迟越低
服务器延迟示例
Wireshark 可以有效的用来识别是网络慢还是应用慢。在 Wireshark 中打开slow_download.pcap
文件,调查下载缓慢的根本原因。
在本例中,从 HTTP 服务器请求 5 MB 的数据,大约需要。4.99 分钟下载,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00056.jpeg
诊断该问题的步骤如下:
- 进入编辑 | 首选项 | 协议 | HTTP 然后启用所有 HTTP 重组选项。
- 应用过滤器
http.response.code==200
。 - 进入 HTTP ,将
http.time == 299.816907000
设置为大约 4.99 分钟。 - 导航至
http.content_length_header == "5242880"
,检查文件的大小;这是内容的大小。 - 检查已经发送了多少个 TCP 数据段—
tcp.segment.count == 2584
—并问自己是否需要这么多,是否可以减少数量。 - 验证客户端和服务器的
window_size
,以检查客户端公布了什么以及使用了什么。 - 在 Wireshark 栏中添加
tcp.window_size_value
并按升序排序。请注意,从服务器(10.0.0.16
)到客户端(122.167.205.152
)的整个数据包流的窗口大小为100
。 - 在 UNIX 风格的系统中验证
sysctl.conf
文件,检查 TCP 调优参数,如net.core.rmem_max
、net.core.wmem_max
、net.ipv4.tcp_rmem
、net.ipv4.tcp_wmemnet.ipv4.tcp_mem
。
Tip
确保tcp.window_size
足够大,以免减慢发送者的速度。窗口大小可以告诉你一个系统在处理输入数据时是否太慢;tcp_window_size
表示系统慢,不是网络。
在这个场景中,sysctl.conf
文件中的tcp.window_size
被缩减,以展示slow_download
行为,并提供对故障排除的深入了解。修复Window_Size
后,同样的下载从299.816907000
减少到2.84
秒。打开fast_download.pcap
文件,如下截图所示;下载时间缩短:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00057.jpeg
电线延迟
在这个示例中,TCP 握手过程将用于识别线路延迟。打开slow_client_ack.pcap
文件,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00058.jpeg
正如您在前面的屏幕截图中看到的:
- 客户机/服务器通过线路发送的前两个握手消息(
SYN
、SYN-ACK
)交换的时间更短 - 在最后一个握手消息中,客户端发送的
ACK
用了frame.time_relative == 15.798777000
秒,显示从参考开始时间增加。这高于前两个握手消息,这证实了此数据包的线路延迟 - 一旦握手完成,操作正常恢复;所有分组的自参考以来的时间显示了一致的定时
Wireshark TCP 序列分析
Wireshark 有一个内置的过滤器tcp.analysys.flags
,它会向您显示包含来自 Wireshark 的某种专家消息的数据包;tcp.analysis.flags
显示在数据包详情窗格的 TCP 部分。在此之下,展开SEQ/确认分析,然后展开 TCP 分析标志。这会告诉你到底是什么触发了tcp.analysis.flags
。一些例子包括:
- TCP 重传
- TCP 快速重传
- tcp 重复确认
- TCP 零窗口
- TCP ZeroWindowProbe
TCP 重传
TCP 通过序列号和确认使数据段的传输变得可靠。当 TCP 传输包含数据的数据段时,它会在重传队列中放置一个副本,并启动一个计时器;收到该数据的确认后,该数据段将从队列中删除。如果在定时器超时前没有收到确认,则重新传输该数据段。在 TCP 重新传输过程中,序列号不会改变,直到发生重新传输超时。
在 Wireshark 中打开示例tcp-retransmission.pcapng
,添加一个序列号列,如以下截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00059.jpeg
正如您在前面的屏幕截图中看到的:
- 在发送
tcp.seq == 1870089183
之后,发生了大量的 TCP 重传 - 大量 TCP 重新传输会导致操作超时
再比如,在 Wireshark 中打开文件syn_sent_timeout_SSH.pcapng
,观察 TCP 重传流程。
Tip
KeepAlive
不是重传。
实验室练习
重现 TCP 重传的步骤如下(本实验在 CentOs6 中使用telnet
和nc
命令实用工具执行):
-
设置两台机器:主机 A(服务器)和主机 B(客户机)。
-
在主机 A 上启动服务器并配置防火墙规则,如下所示:
[bash ~]# iptables -A OUTPUT -p tcp --dport 8082 -j DROP [bash ~]# iptables save [bash ~]# nc -l 8082
-
在 HOST-B 机器上打开 Wireshark,开始捕获数据包,并选择 display filter
tcp.port==8082
。 -
在 HOST-B 机器上运行 telnet 命令;将 IP 信息更改为您的实际服务器位置:
[bash ~]telnet 128.136.179.233 8082
-
验证主机 B 机器上的 TCP 状态:
bash$ netstat -an | grep 8082 tcp4 0 0 192.168.1.101.64658 128.136.179.233.8082 SYN_SENT
-
在 Wireshark 中,使用上一步查看并分析捕获的数据包。
为了解决操作超时问题,请检验 ACL 配置;它允许来自源 IP 的传入数据包。
TCP 零窗口
在 Wireshark 中打开的tcp_zero_window.pcapng
文件,并将tcp.window_size_value
添加到该列中。
TCP 窗口大小表示在将数据传递到应用进程之前,设备一次可以处理来自对等方的多少数据。
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00060.jpeg
如前面的屏幕截图所示:
- 将
window_size
添加到 Wireshark 列,并在tcp.window_size=0
处查找数据包。 - 窗口大小为零的 TCP 报头表示接收方的缓冲区已满。这种情况对于写入来说比读取来得更快;在这种情况下,
tcp.window_size_value
被设置为0
和tcp.window_size == 0
。 - 该段正好是 1 个字节。
Tip
TCP ZeroWindow 上从不设置SYN
/ RST
/ FIN
标志。
SYN
/RST
/FIN
TCP 窗口满时从不设置标志。
零窗口条件故障排除:
-
检查应用是否有足够的内存来启动
-
调整 TCP 参数以获得更大的窗口大小;用这些参数检查
sysctl.conf
文件:net.core.rmem_max
net.core.wmem_max
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem
-
检查接收器没有运行太多进程
TCP 窗口更新
当窗口大小改变时,Wireshark 将数据包标记为窗口更新。窗口更新是一个ACK
包,只扩展窗口;这是正常的 TCP 行为。
在 Wireshark 中打开tcp_window_update.pcap
文件,观察到设置了一个 TCP 窗口更新事件,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00061.jpeg
注意
窗口更新是一个 0 字节的数据段,其SEQ
/ ACK
号与之前看到的数据段相同,并且具有一个新的窗口值。
TCP Dup 备份
当有快速重传时,发送重复的 ack。在这种情况下,将会经常看到相同的片段。打开duplicate_ack.pcapng
并应用tcp.analysis.duplicate_ack
滤镜,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00062.jpeg
正如你在前面的截图中看到的:
- 当窗口/SEQ/ACK 与前一段相同并且段长度为
0
时,出现重复 ACK - 当有数据包丢失时,可能会出现重复的 ack,在这种情况下,可以看到重传
参考文献
在使用 TCP/IP 无限制时,以下参考资料将会很有用:
- RFC675 TCP/IP 第一规范:https://tools.ietf.org/html/RFC675
- RFC 793TCP v4:https://tools.ietf.org/html/RFC793
- TCPWiki:https://en.wikipedia.org/wiki/Transmission_Control_Protocol
- TCP/IP 指南:http://www.tcpipguide.com/
- 请通过https://ask.wireshark.org/向 Wireshark 咨询所有与 Wireshark 相关的问题
- 在:https://www.wireshark.org/docs/dfref/t/tcp.html显示 TCP 的过滤器引用
- TCP 在:https://wiki.wireshark.org/TCP_Analyze_Sequence_Numbers分析序列号
- 有用的剪辑:https://goo.gl/lVaEc9
总结
在本章中,你已经学习了 TCP 如何打开和关闭它的连接,以及在此期间 TCP 状态是如何保持的。本章还讲述了网络上出现的错误模式以及如何排除这些情况的故障。
在下一章中,我们将实现 SSL 协议的深度包检查。
四、分析 SSL/TLS
在本章中,我们将通过以下主题了解 SSL/TLS 的用途、整个握手过程是如何进行的,以及 SSL/TLS 握手失败的常见情况:
- SSL/TLS 简介
- Wireshark 的 SSL/TLS 握手协议
- SSL/TLS—使用 Wireshark 解密通信
- SSL/TLS—调试握手问题
SSL/TLS 简介
传输层安全 ( TLS )是安全套接字层 ( SSL )的新名称。它提供了应用之间的安全传输连接,具有以下优势:
- SSL/TLS 代表更高层的协议在第 7 层(应用层)工作
- SSL/TLS 通过加密通信来提供机密性和完整性
- SSL/TLS 允许对封闭用例进行客户端验证(可选)
SSL/TLS 版本
在调试握手问题时,了解版本是极其重要的,因为大多数握手失败都发生在这个过程中。
Netscape 开发了最初的 SSL 版本和其他版本;它们的 RFC 编号如下表所示:
|
草案
|
年
|
请求评论
|
反对
|
| — | — | — | — |
| SSL 1.0 | 不适用的 | 不适用的 | 不适用的 |
| SSL 2.0 | One thousand nine hundred and ninety-five | 钠 | Y RFC 6176 |
| SSL 3.0 | One thousand nine hundred and ninety-six | RFC 6101 | Y RFC 7568 |
| TLS 1.0 | One thousand nine hundred and ninety-nine | RFC 2246 | 普通 |
| TLS 1.1 | Two thousand and six | RFC 4346 | 普通 |
| TLS 1.2 | Two thousand and eight | RFC 5246 | 普通 |
| TLS 1.3 | TBD | 起草 | 普通 |
SSL/TLS 组件
SSL/TLS 分为四个主要的组件,如下图所示,本章将逐一详细介绍所有组件:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00063.jpeg
SSL/TLS 握手
TLS 握手协议负责建立或恢复安全会话所需的认证和密钥交换。握手协议管理以下内容:
- 客户端和服务器将就密码套件协商、随机值交换和会话创建/恢复达成一致
- 客户端和服务器将获得预主秘密
- 客户端和服务器将交换它们的证书以向客户端验证它们自己(可选)
- 从预主秘密生成主秘密并交换它
握手消息的类型
有十种类型的消息,如下表所示,以及它们对应的 Wireshark 过滤器。这是握手协议中的一个字节字段:
|
类型
|
草案
|
消息
|
Wireshark 内容类型
|
Wireshark 过滤器
|
| — | — | — | — | — |
| Zero | 握手 | 你好请求 | ssl.record.content_type == 22
| ssl.handshake.type == 0
|
| one | 客户你好 | ssl.handshake.type == 1
|
| Two | 服务器你好 | ssl.handshake.type == 2
|
| Eleven | 证书 | ssl.handshake.type == 11
|
| Twelve | 服务器密钥交换 | ssl.handshake.type == 12
|
| Thirteen | 证书申请 | ssl.handshake.type == 13
|
| Fourteen | 服务器 HelloDone | ssl.handshake.type == 14
|
| Fifteen | 证书验证 | ssl.handshake.type == 15
|
| Sixteen | 客户端密钥交换 | ssl.handshake.type == 16
|
| Twenty | 完成 | ssl.handshake.type == 20
|
| | ChangeCipherSpec | | ssl.record.content_type == 20
| |
| 应用数据 | ssl.record.content_type == 23
|
| 警报协议 | ssl.record.content_type == 21
|
TLS 握手协议包括以下四个阶段的步骤:先决条件是应该建立 TCP 连接:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00064.jpeg
打开文件two-way-handshake.pcap
,这是一个演示 SSL 相互认证过程的示例:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00065.jpeg
客户您好
TLS 握手从客户端问候消息ssl.handshake.type == 1
开始,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00066.jpeg
握手记录被识别为十六进制字节0x16=22
。客户端问候消息的结构如下:
-
消息:客户端您好消息
0x01
。 -
版本:十六进制字节
0x0303
表示是 TLS 1.2 注意0x300 =SSL3.0
。 -
随机 :
gmt_unix_time
:标准 UNIX 32 位格式的当前时间和日期Random bytes
:由安全随机数
生成的 28 字节
-
会话 ID :十六进制字节
0x00
显示会话 ID 为空;这意味着没有会话可用,并生成新的安全参数。 -
Cipher suites: The client will provide a list of supported cipher suites to the server; the first cipher suite in the list is the client-preferred (the strongest) one. The server will pick the cipher suites based on its preferences, the only condition being that the server must have client-offered cipher suites otherwise the server will raise an alert/fatal message and close the connection:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00067.jpeg
-
压缩方式:客户端会列出其支持的压缩方式。
-
扩展:客户端利用扩展向服务器请求扩展功能;在这种情况下,客户端请求了四个扩展,如下表所示:
|
价值
|
扩展名
|
参考
|
| — | — | — |
| Zero | elliptic_curve
| RFC4492 |
| one | ec_point_formats
| RFC4492 |
| three | signature_algorithms
| RFC 5246 |
| five | heartbeat
| RFC 6520 |
注意
有关 TLS 扩展的完整列表,请访问:http://www . iana . org/assignments/TLS-extension type-values/TLS-extension type-values . XHTML。
服务器你好
服务器将发送服务器问候消息(ssl.handshake.type == 2
)来响应客户端问候,如下面的截图所示。客户端 Hello 和服务器 Hello 消息的消息结构是相同的,只有一点不同,即服务器只能选择一个密码套件:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00068.jpeg
握手记录被识别为十六进制字节0x16=22
。服务器问候消息的结构是:
-
握手类型:第个十六进制字节
0x02=2
显示服务器 Hello 消息 -
版本:十六进制字节
0x0303
显示 TLS 1.2 has 已被服务器接受服务器/客户端【sslv 2】【slv 3】【ssv 23】
普通
普通
普通
普通
【sslv 3】
普通
和
普通
普通
普通
【
【ssv 23】【
普通
【
【
和
【
【【【
【)和
普通
普通
普通
【
普通
【tlsv 1.1】
普通
普通
普通
和
普通
【tlsv 1.2】
普通
普通
和
普通
普通
和
下表显示了哪个 SSL 版本的客户端可以连接到哪个 SSL 版本的服务器:
- 会话 ID :创建一个 32 字节的会话 ID,用于重新连接,无需握手
- 密码套件 : 服务器选择了
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
,这意味着使用椭圆曲线 Diffie-Hellman(ECDHE)密钥交换,RSA 用于认证,分组密码 Galois/Counter Mode (GCM),AES-256 用于加密,SHA-384 用于摘要 - 扩展:在客户端问候消息中请求带有扩展信息的响应
服务器证书
服务器 Hello 消息发出后,服务器要发送一个 X.509 服务器证书(ssl.handshake.type == 11
)。服务器上配置的证书由 CA 或中间 CA 签名,也可以根据您的部署进行自签名:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00069.jpeg
如果 SSL/TLS 服务器配置了证书链,则整个证书链将与服务器证书一起呈现给客户端。然后,客户端(浏览器或任何其他 SSL/TLS 客户端)可以用存储的 CA 证书检查链中的最高证书;通常,现代 Web 浏览器安装了来自可信 CA 提供商的根 CA。
给定证书由相关签名(sha256WithRSAEncryption
)签署;在这种情况下,哈希值本身被连接到代表签名算法的 OID ( Algorithm Id: 1.2.840.113549.1.1.11
)中。证书遵循 DER 编码格式,加密后成为加密消息语法标准 PKCS#7(参考 RFC 2315)。
服务器密钥交换
根据 RFC #5246,服务器仅在服务器证书消息(如果发送的话)不包含足够的数据来允许客户端交换预主密钥时,才发送服务器密钥交换消息(ssl.handshake.type == 12
):
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00070.jpeg
正如你在前面的截图中看到的:
- 密码套件包含密钥交换算法
- 将为以下密钥交换方法发送服务器密钥交换消息:
DHE_DSS
,DHE_RSA,DH_anon
- 根据 RFC#5246,使用服务器密钥交换对于以下密钥交换方法是不合法的:
RSA
、DH_DSS
、DH_RSA
客户端证书请求
服务器可以选择性地要求客户端验证它的证书。为了支持相互认证,服务器将向客户端发送证书请求消息(ssl.handshake.type == 13
),客户端必须向服务器提供其证书信息。如果客户端无法提供,将生成一个警报协议,连接将终止。
服务器你好完成
服务器 Hello Done 消息意味着服务器完成了发送消息以支持密钥交换,并且客户端可以继续其密钥交换阶段:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00071.jpeg
客户证书
只有在相互认证的情况下,客户端才会向发送其证书(ssl.handshake.type == 11
)。服务器将在其 CA 链中验证证书。如果服务器验证client_certificate
失败,服务器将发出致命协议警报,通信将停止:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00072.jpeg
客户端密钥交换
在正常握手过程(单向认证)的情况下,客户端密钥交换消息是客户端收到服务器 Hello Done 消息后发送的第一条消息。
该客户端密钥交换消息(ssl.handshake.type == 16
)将始终由客户端发送。当看到该消息时,pre_master_secret
被设置,或者通过传输 RSA 加密的秘密,或者通过 Diffie-Hellman 参数,这取决于所选择的密钥交换方法。服务器使用自己的私钥解密premaster_secret
:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00073.jpeg
客户端证书验证
客户端证书验证消息将在pre_master_secret
使用master_secret
生成的客户端密钥交换消息ssl.handshake.type == 16
之后发送。
更改密码规格
更改密码规范记录类型(ssl.record.content_type == 20
)不同于握手记录类型(ssl.record.content_type == 22
),它是更改密码规范协议的一部分。仅当key_exchange
完成时,客户端和服务器才发送更改密码规范消息,该消息向接收方指示后续记录将在新协商的更改密码规范和密钥下受到保护(master_secret
):
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00074.jpeg
完成了
完成(ssl.record.content_type == 22
)消息被加密,因此它将是 Wireshark 中的加密握手消息。客户端和服务器发出更改密码规范消息后,会立即发送此消息,以验证密钥交换和身份验证过程是否成功。该消息包含 MD5 散列+SHA 散列。当客户端和服务器都发送了完成的消息时,TLS 握手被认为已经成功完成,现在可以开始通过安全通道发送和接收应用数据了:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00075.jpeg
应用数据
应用数据消息(ssl.record.content_type == 23
)由记录层承载,并被分段、压缩和加密:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00076.jpeg
记录层处理包括上述步骤,如下图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00077.jpeg
警报协议
警报协议(ssl.record.content_type == 21
)描述了消息和警报的严重程度。Alert 消息经过加密和压缩,支持两种警报级别:警告和致命。在致命警报的情况下,连接将被终止。
下表显示了警报描述:
|
警报名称
|
警报类型
|
描述
|
| — | — | — |
| close_notify(0)
| 关闭警报 | 发件人将不再在此连接上发送任何消息 |
| unexpected_message(10)
| 致命的 | 收到了一个适当的消息 |
| bad_record_mac(20)
| 致命的 | 收到不正确的 MAC |
| decryption_failed(21)
| 致命的 | TLS 密文以无效方式解密 |
| record_overflow(22)
| 致命的 | 消息的大小超过了 2^14+2048 字节 |
| decompression_failure(30)
| 致命的 | 收到无效输入 |
| handshake_failure(40)
| 致命的 | 发送方无法完成握手 |
| bad_certificate(42)
| 致命的 | 收到了损坏的证书;错误的 ASN 序列 |
| unsupported_certificate(43)
| 致命的 | 不支持证书类型 |
| certificate_revoked(44)
| 警告 | 签名者已经撤销了证书 |
| certificate_expired(45)
| 警告 | 证书无效 |
| certificate_unknown(46)
| 警告 | 证书未知 |
| illegal_parameter(47)
| 致命的 | TLV 包含无效参数 |
| unknown_ca(48)
| 致命的 | 找不到 CA 链 |
| access_denied(49)
| 致命的 | 证书有效,服务器拒绝协商 |
| decode_error(50)
| 致命的 | 收到的 TLV 没有有效的形式 |
| decrypt_error(51)
| 致命的 | 解密密码无效 |
| export_restriction(60)
| 致命的 | 检测到不符合出口限制的谈判 |
| protocol_version(70)
| 致命的 | 服务器不支持所选的协议版本 |
| insufficient_security(71)
| 致命的 | 需要强大的密码套件 |
| internal_error(80)
| 致命的 | 与服务器相关的问题 |
| user_canceled(90)
| 致命的 | 客户端取消了操作 |
| no_renegotiation(100)
| 致命的 | 服务器无法协商握手 |
如以下屏幕截图所示,警报协议由服务器生成:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00078.jpeg
密钥交换
在接下来的小节中,我们将讨论 SSL/TLS 通道是如何被解密的;在此之前,我们需要了解不同的密钥交换方法是什么,以及它们的密码套件是什么样的。这些是下面的密钥交换方法。
Diffie-Hellman 密钥交换
该协议允许两个用户在没有任何先验秘密的情况下通过不安全的介质交换密钥;在这个方案中,示例密码套件将具有一个命名约定,例如:
- SSL_DH_RSA_WITH_DES_CBC_SHA
- SSL _ DH _ RSA _ WITH _ 3d es _ EDE _ CBC _ SHA
密码套件的名称中会有“DH”,而不是“DHE”或“DH_anon”。
注意
你可以通过https://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange了解更多关于迪菲-海尔曼的信息。
椭圆曲线 Diffie-Hellman 密钥交换
椭圆曲线 Diffie-Hellman 是一种改进的 Diffie-Hellman 交换,它使用椭圆曲线加密代替传统的 RSA 风格的大素数。椭圆曲线 密码学 ( ECC )和 RSA、Rabin、El Gamal 一样都是公钥密码系统。该算法的一些要点是:
- 每个用户都有一个公钥和一个私钥
- 公钥用于加密/签名验证
- 私钥用于解密/签名生成
注意
你可以在:https://en.wikipedia.org/wiki/Elliptic_curve_Diffie–Hellman了解更多关于椭圆曲线的信息。
注意,提供了扩展椭圆曲线密钥交换中的客户端 Hello 消息交换过程。示例密码套件将遵循命名约定,例如:
- SSL_DHE_RSA_WITH_DES_CBC_SHA
- SSL _ dhe _ RSA _ with _ 3 des _ ede _ CBC _ sha
密码套件的名称中会有“DHE”,而不是“DH”或“DH_anon”。
的话
在服务器密钥交换握手期间,服务器的公共密钥可供客户机使用。pre_master_secret
密钥是用服务器公开的 RSA 密钥加密的。在这种情况下,示例密码套件将是:
- SSL_RSA_WITH_RC4_128_SHA
- SSL _ RSA _ 带 _DES_CBC_SHA
- TLS_RSA_WITH_AES_128_CBC_SHA
密码套件的名称中会有“RSA ”,而不是“DH”、“DH_anon”或“DHE”。
解密 SSL/TLS
到目前为止,我们已经了解了 SSL/TLS 协议如何加密流量并保持机密性。在下一节中,我们将介绍 Wireshark 如何帮助解密 SSL/TLS 流量。
解密 RSA 流量
TLS 流量的解密取决于服务器在服务器问候消息中选择的密码套件。打开文件decrypt-ssl-01.pcap
,寻找服务器选择的密码。在这种情况下,使用了 TLS_RSA_WITH_AES_256_CBC_SHA 密码套件;因为这是 RSA,我们可以用我们的私钥解密包。
现在进入编辑 | 首选项 | 协议 | SSL ,添加新的 RSA 密钥,并配置 RSA 密钥对话框的以下属性:
- 私有的密钥文件(此处为
server.key
,由服务器使用)。 - 服务器的 IP 地址。
- SSL/TLS 服务器的端口(
443
)。 - The decoding protocol—use
http
in this case.https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00079.jpeg
应用这些设置后,SSL 流量将被解码为该 IP 的 HTTP 流量,如以下屏幕截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00080.jpeg
一旦数据包被解密,就可以通过点击文件 | 导出 SSL 会话密钥来导出 SSL 会话。将打开一个对话框;将该会话密钥保存在文件中(exported-session-keys
)。文件的内容如下所示:
RSA Session-ID:af458c9c61675238b74f40b2a9547a0a2a394ada458a1b648e0495ed279d5e2e Master-Key:6c970211a77548811267646a759d0d03bbc532d9b6336f2b656cb0c6bbef8f3a262d845b9abed87d26583a9c4bb9b230
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00081.jpeg
一旦创建了exported-session-keys
文件,就使用这个文件来解密 SSL/TLS 流量。为此,请转到编辑 | 首选项 | 协议 | SSL ,并使用 SSL 会话密钥的路径配置(预)主密钥日志文件。当用户希望共享数据包而不共享私钥,并且仍然需要提供解密步骤时,这种方法非常有用:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00082.jpeg
解密 DHE/埃切德流量
DHE/ECDHE 不能用这种方法解密,即使我们有私钥,因为它们被设计成支持前向保密。
向前保密
在Diffie-Hellman(DHE)和椭圆曲线密码 Diffie-Hellman(ECDHE)密钥交换算法中支持前向保密。以之前的场景为例;SSL/TLS 通信可以通过知道服务器的私钥来解密。如果私钥被不良的系统强化或(内部威胁代理)破坏,SSL/TLS 通信可能会中断。在前向保密中,即使我们可以访问服务器的私钥,SSL/TLS 通信也是安全的。
如果密码套件的名称包含“ECDHE”或“DHE”,这意味着它支持前向保密。例如,注意这个密码套件名称:TLS_ECDHE_RSA_WITH_RC4_128_SHA。
注意
此的一些有用参考如下:
- http://security . stack exchange . com/questions/35639/decrypting-TLS-in-wireshark-when-using-dhe-RSA-cipher suites/42350 # 42350
- https://wiki.wireshark.org/SSL
- https://weakdh.org/
- https://www.openssl.org/docs/apps/ciphers.html
- https://goo.gl/9YU0HC
调试问题
在本节中,我们将学习如何调试常见的 SSL 相关问题:
-
了解你的 SSL/TLS 服务器。如何配置服务器、使用哪个 TLS 版本以及它支持哪些密码套件非常重要。为此,使用如下所示的
nmap
实用工具:root@bash :/home/ubuntu# nmap --script ssl-cert,ssl-enum-ciphers -p 443 10.0.0.106 Starting Nmap 6.40 ( http://nmap.org ) at 2015-08-03 16:49 UTC Nmap scan report for ip-10-0-0-106.ap-southeast-1.compute.internal (10.0.0.106) Host is up (0.000067s latency). PORT STATE SERVICE 443/tcp open https | ssl-cert: Subject: commonName=ip-10-0-0-106/organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU | Issuer: commonName=ip-10-0-0-106/organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU | Public Key type: rsa | Public Key bits: 2048 | Not valid before: 2015-07-28T14:43:45+00:00 | Not valid after: 2016-07-27T14:43:45+00:00 | MD5: 9ba5 0ea9 14b2 0793 7fe6 9329 08ce fab3 |_SHA-1: 1604 27b6 4f1c a838 9a9d db67 3136 88de effb f881 | ssl-enum-ciphers: | TLSv1.2: | ciphers: | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong | compressors: | NULL |_ least strength: strong
-
nmap
输出显示服务器支持 TLSv1.2 和一个密码套件。如果客户端使用服务器不支持的其他 SSL 协议或密码套件进行连接,服务器将返回握手失败。比如用 TLSv1.1 连接同一个服务器会返回错误:rootbash # curl -k --tlsv1.1 https://10.0.0.106 curl: (35) Unknown SSL protocol error in connection to 10.0.0.106:443
-
用服务器不支持的密码连接会返回握手错误,如下图:
root@bash # curl -k --ciphers EXP-RC2-CBC-MD5 https://10.0.0.106 curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
-
接收
unknown_ca
错误检查以下从证书、私钥和 CSR 文件中查找哈希值使用以下命令:bash $ openssl x509 -noout -modulus -in server.crt | openssl md5 f637e8d51413ff7fa8d609e21cb27244 bash $ openssl rsa -noout -modulus -in server.key | openssl md5 f637e8d51413ff7fa8d609e21cb27244 bash $ openssl req -noout -modulus -in server.csr | openssl f637e8d51413ff7fa8d609e21cb27244
如果csr
是用客户端私钥生成的,那么csr
、cer
的 md5 哈希值和私钥将是相同的,尽管证书是用 CA(中间 CA)私钥生成的。
如果 md5 文件相同,则验证 CA 颁发的证书与其路径匹配:
bash $ openssl verify -verbose -CAfile cacert.pem server.crt
bash $ openssl verify -verbose -CAfile cacert.pem client.crt
注意
SSL 测试的有用参考资料:
- https://www.ssllabs.com/ssltest/
- https://github.com/rbsec/sslscan
- https://testssl.sh/openssl-rfc.mappping.html
总结
在本章中,我们学习了 SSL/TLS 握手协议的工作原理,以及如何使用 Wireshark 对其进行分析。我们已经检查了与握手相关的示例调试问题,并学习了如何解决它们。在下一章中,我们将借助 Wireshark 继续分析其他应用层协议。
五、分析应用层协议
在前一章中,我们详细介绍了 SSL/TLS 应用层协议。在本章中,我们将继续学习其它应用层协议(它们的基本流和一些通用用例),并了解如何生成这些类型的流量:
- DHCPv6
- DHCv4
- 域名服务器(Domain Name Server)
- 超文本传送协议
DHCPv6
IPv6 的 动态主机配置协议 ( DHCPv6 )是一个应用层协议,为 DHCPv6 客户端提供 IPv6 地址和其他配置信息,这些信息在 DHCPv6 选项中携带。
DHCPv6 既是有状态地址自动配置协议,也是无状态地址配置协议。
客户端和服务器通过 UDP 交换 DHCPv6 消息;客户端使用链接本地地址,DHCPv6 通过链接范围的多播地址接收消息。如果 DHCPv6 服务器没有连接到同一链路,则客户端链路上的 DHCPv6 中继代理将在 DHCPv6 客户端和 DHCPv6 服务器之间中继消息,如以下屏幕截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00083.jpeg
DHCPv6 Wireshark 过滤器
使用 dhcpv6
显示过滤器来显示 DHCPv6 流量。对于捕获过滤器,使用 UDP 端口547
。
组播地址
DHCPv6 客户端使用多播地址向一组 DHCPv6 服务器发送数据报:
- 对于所有 DHCP 中继代理和服务器,地址是
FF02::1:2
(链接本地) - 对于所有 DHCPv6 服务器,地址是
FF05::1:3
(本地站点)
UDP 端口信息
服务器和中继代理监听 UDP 端口547
上的 DHCPv6 消息;客户端在 UDP 端口546
上监听 DHCPv6 消息。要查找端口信息,可以使用netstat
命令:
[root@bash ~]# netstat -an | grep 547
udp 0 0 :::547 :::*
DHCPv6 消息类型
DHCPv6 消息通过 UDP 端口546
和547
交换,消息描述如下表:
|
DHCPv6 消息
|
描述
|
DHCPv6 Wireshark 筛选器
|
IPv4 消息的等效 DHCP
|
| — | — | — | — |
| SOLICIT
| 该消息由客户端发送到一组 DHCPv6 服务器 | dhcpv6.msgtype == 1
| DHCPDISCOVER
|
| ADVERTISE
| 该消息由服务器发送,显示了 DHCPv6 服务的服务器可用性,以响应SOLICIT
消息 | dhcpv6.msgtype == 2
| DHCPOFFER
|
| REQUEST
| 此消息将由客户端发送,包含 IPV6 地址或配置参数 | dhcpv6.msgtype == 3
| DHCPREQUEST
|
| CONFIRM
| 该消息将由客户端发送,以确认 IPv6 地址对于该链路是否仍然有效 | dhcpv6.msgtype == 4
| DHCPREQUEST
|
| RENEW
| 客户端将发送此消息来更新其生存期或其他配置参数 | dhcpv6.msgtype == 5
| DHCPREQUEST
|
| REBIND
| 如果没有收到RENEW
消息,客户端将发送该消息,并更新其 IPv6 地址和其他配置参数 | dhcpv6.msgtype == 6
| DHCPREQUEST
|
| REPLY
| 对于客户端发送的每条消息,将从服务器接收到一条REPLY
消息 | dhcpv6.msgtype == 7
| DHCPACK
|
| RELEASE
| 客户端将发送此消息以释放 IPv6 地址和其他配置参数 | dhcpv6.msgtype == 8
| DHCPRELEASE
|
| DECLINE
| 如果客户端发现 IPv6 地址已经分配并正在使用中,将会发送此消息 | dhcpv6.msgtype == 9
| DHCPDECLINE
|
| RECONFIGURE
| 此消息将由服务器发送,以指示配置参数已更新或已更改;客户端将发送一个RENEW
/ REPLY
或INFORMATION-REQUEST
/ REPLY
来获取更新的配置 | dhcpv6.msgtype == 10
| 不适用的 |
| INFORMATION-REQUEST
| 此消息将由配置请求无 IPv6 地址分配的客户端发送 | dhcpv6.msgtype == 11
| DHCPINFORM
|
| RELAY-FORWARD
| 此消息将由中继代理发送,以便将消息转发给服务器。RELAY-FORWARD
包含封装为 DHCPv6 RELAY
消息选项的客户端消息 | dhcpv6.msgtype == 12
| 不适用的 |
| RELAY-REPLY
| 这条消息将由服务器通过中继代理发送给客户端。RELAY-REPLY
包含封装为 DHCPv6 RELAY
消息选项的服务器消息 | dhcpv6.msgtype == 13
| 不适用的 |
消息交流
DHCPv6 消息交换是为了获取 IPv6 地址、配置(NTP 服务器、DNS 服务器)或 IPv6 地址的RENEW
/ RELEASE
/ DECLINE
,这些消息交换分为两部分:
- 具有四个消息交换的客户机-服务器
- 具有双消息交换的客户机-服务器
四条信息的交换
四消息交换的首字母缩写是 SARR ,它用于请求分配一个或多个 IPv6 地址。消息流如下所示:
SOLICIT
ADVERTISE
REQUEST
REPLY
在 Wireshark 中打开DHCPv6-Flow-SOLICIT.pcap
文件,检查 IP 分配流程,如图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00084.jpeg
前面的屏幕截图显示了一个被捕获的 SARR 流数据包。IPv6 被分配给 DHCPv6 客户端,具体的消息交换是:
-
SOLICIT
:客户端(fe80::f816:3eff:fe1d:e848
)发送SOLICIT
消息定位服务器。注意目的地是多播ff02::1:2
而不是服务器(目的地)IPv6 地址:- 客户端包括其客户端标识符选项
dhcpv6.option.type == 1
。 - 客户端将其 ORO 选项(
dhcpv6.option.type == 6
)发送给有兴趣接收的服务器。在这种情况下,客户端请求名称服务器信息。 - 在本例中,客户端使用 IA_NA 选项请求分配非临时地址(
dhcpv6.option.type == 3
),并使用 IA_TA 选项请求分配临时地址。 - 客户端 IA 地址选项用于指定与 IA_NA 或 IA_TA 关联的 IPv6 地址。在本例中,它与 IA_NA 相关联。
- 客户端包括其客户端标识符选项
-
ADVERTISE
:服务器(fe80::f816:3eff:fe1d:e848
)发送ADVERTISE
(dhcpv6.msgtype == 2
)消息给客户端(fe80::f816:3eff:fe1d:e848
)。可以有多个服务器响应客户端SOLICIT
消息;客户端会根据自己的喜好选择 DHCPv6 服务器:- 服务器根据自己的喜好更新 IA_NA (
dhcpv6.option.type == 3
)值。 - 服务器包含其服务器标识符(
dhcpv6.option.type == 2
)信息。服务器标识符选项用于携带 DUID。 DUID 是 DHCP 唯一标识符,IPv6 中的主机标识符。(在 DHCPv4 的情况下,主机标识符是 MAC 地址。) - 服务器包括在
SOLICIT
消息中请求的名称服务器(dhcpv6.option.type == 23
)信息。 - 在这种情况下,服务器事务 ID
0x10eafe
必须与客户端事务 IDSOLICIT
匹配。
- 服务器根据自己的喜好更新 IA_NA (
-
REQUEST
: In this message the client chooses one of the servers and sends aREQUEST
message to the server asking for confirmed assignment of addresses and other configuration information:- 客户端(
fe80::f816:3eff:fe1d:e848
)构造REQUEST
数据包并将其发送给组播ff02::1:2
- 客户端包含一个新的交易 ID:
0x3ec03e.(random)
- 客户端在
REQUEST
数据包中包含服务器标识符信息
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00085.jpeg
- 客户端(
-
REPLY
:在有效的REQUEST
消息的情况下,服务器根据服务器的策略和配置信息为该客户端创建绑定,记录 IAs 和客户端请求的其他信息,并通过设置dhcpv6.msgtype == 7
:- 发送
REPLY
消息服务器事务 ID0x3ec03e
将与客户端 DHCv6REQUEST
消息事务 ID - 服务器将包括服务器标识符和客户端标识符
REPLY
消息将是其中的一部分
- 发送
双信息交换
当不需要分配 IP 地址时,或者当 DHCPv6 客户端希望获得配置信息(如可用 DNS 服务器或 NTP 服务器的列表)时,客户端和服务器之间将执行双消息交换,例如CONFIRM-REPLY
和RELEASE-REPLY
。在 Wireshark 中打开示例DHCPv6-Flow-CONFIRM-RELEASE.pcap
文件,它显示执行了两个消息的交换:
-
DHCPv6 messages
CONFIRM-REPLY
andRELEASE-REPLY
:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00086.jpeg -
DHCPv6 messages
INFOMRATION-REQUEST
: The client sends theINFORMATION-REQUEST
when the client requests configuration settings (but not addresses)—for example, DNS, NTP. As shown in the following screenshot, open theDHCPv6-Information_request.pcap
file in Wireshark:- 客户端将设置
dhcpv6.msgtype == 11
:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00087.jpeg
- 客户端将设置
-
The rapid commit option is used to obtain the IPv6 address assignment in the two-message exchange, as shown in the following screenshot example,
DHCPv6-Rapid-Commit.pcap
. Note that rapid commit is not a separate DHCPv6 message and is part of theSOLICIT
option:https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00088.jpeg- 如果支持快速提交选项的客户端打算使用快速提交功能,它会在其发送的
SOLICIT
消息中包含一个快速提交选项。 - 如果客户端收到带有快速提交选项的
REPLY
消息,它应该立即处理REPLY
(不等待额外的ADVERTISE
或REPLY
消息)并使用其中包含的地址和配置信息。 - 如果服务器不支持快速提交选项,那么它将遵循四个消息交换(请求、广告、请求、以及回复被称为 SARR) 。
- 如果支持快速提交选项的客户端打算使用快速提交功能,它会在其发送的
DHCPv6 流量捕获
使用dhclient
到模拟网络上的 DHCPv6 流量。为此,请执行以下操作:
-
确保设置了 DHCPv6 服务器。这个例子是在 ISC 动态主机配置服务器 ( dhcpd )服务器上执行的。
-
Run the
tcpdump
utility to capture IPv6 traffic:bash$ tcpdump -i any ip6 -vv -w DHCPv6-FLOW.pcap -s0 &
确保 DHCPv6 服务器正在您的网络中运行。
-
捕获一个 DHCPv6 四消息交换(SARR):
bash$ dhclient -6 eth0
-
捕获 DHCPv6
RELEASE
报文:bash$ dhclient -6 -r eth0
-
捕获 DHCPv6
CONFIRM
报文:bash$ dhclient -6 eth0
-
捕获 DHCP V6
INFORMATION
请求:bash$ dhclient -S -6 eth0
BOOTP/DHCP
DHCP 是 BOOTP 机制的扩展。换句话说,DHCP 使用 BOOTP 作为它的传输协议。此行为允许现有的 BOOTP 客户端与 DHCP 服务器互操作,而不需要对客户端的初始化软件进行任何更改;下表显示了这两种协议之间的基本比较:
|
BOOTP/DHCP
|
引导协议(BOOTstrapping Protocol)
|
动态主机配置协议
|
| — | — | — |
| 意义 | 引导协议 | BOOTP 的动态主机配置协议扩展 |
| 年 | One thousand nine hundred and eighty-five | One thousand nine hundred and ninety-three |
| UDP 服务器端口 | Sixty-seven |
| UDP 客户端端口 | sixty-eight |
| 服务 |
- IPv4 address assignment
- Get IPv4 configuration parameters
- A limited number of client configuration parameters are called vendor extensions.
|
- IP address assignment
- lease
- Support traditional BOOTP function
- DHCP supports a larger and extensible set of client configuration parameters called options.
|
| 请求评论 | RFC951 | RFC 2131 |
| 存在 | 被动态主机配置协议(DHCP)取代 | 活跃;RFC 不断加入更多的特性并支持不同的技术需求 |
BOOTP/DHCP Wireshark 过滤器
使用bootp
过滤器显示 BOOTP/DHCP 流量,并使用 UDP 端口67
仅捕获 BOOT/DHCP 流量。
地址分配
DISCOVER
、OFFER
、REQUEST
、ACK
在网络地址分配过程中,客户端和服务器之间发生协议交换,如下图所示。作为助记符,将此称为朵拉。
也可以使用 DHCPv4 的快速提交选项来完成地址分配。它模仿 DHCPv6,使用双消息交换来快速配置 DHCPv4 客户端。
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00089.jpeg
要演示四条消息的交换,请在 Wireshark 中打开DHCPv4.pcap
文件,如下面的截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00090.jpeg
上图显示了 DHCPv4 客户端和 DHCPv4 服务器之间发生的消息交换。这概括如下:
-
DISCOVER (bootp.option.dhcp == 1)
:- 展开 Bootstrap 协议查看 BOOTP 详情
- 客户端在其本地物理子网广播
255.255.255.255``DHCPDISCOVER
消息,可能包括选项:(55
即bootp.option.type
参数请求列表;在此期间,“yiaddr”字段将为(bootp.ip.your == 0.0.0.0
)
-
OFFER (bootp.option.dhcp == 2)
:- 展开引导协议以查看 BOOTP 详细信息
- DHCP 服务器可以用在“yiaddr”(
bootp.ip.your == 10.0.0.106
)字段 - 中包括可用网络地址的
DHCPOFFER
消息来响应。DHCP 服务器将发送其选项 54: DHCP 服务器标识符,并且可以包括选项 55 中请求的其他配置参数DICOVER
阶段
-
DHCPREQUEST (bootp.option.dhcp == 3)
:- 展开 BOOTP 协议以查看 BOOTP 详细信息
- 客户端广播(
255.255.255.255
)一条DHCPREQUEST
消息,要求必须包含选项 54 DHCP 服务器标识符以指示其已选择的服务器,并且可以包含指定所需配置值的其他选项 DHCPREQUEST
消息中选择的 DHCP 服务器将客户端的绑定提交给db
存储,并以 ACK
响应
-
*
ACK (bootp.option.dhcp == 5)
:- 展开 Bootstrap 协议查看 BOOTP 详情
- 服务器将 ACK 连同配置参数一起发送给客户端;在此期间,IPv4 地址将为“yiaddr”(
bootp.ip.your == 10.0.0.106
) - 。客户端将验证获得的配置,并使用 ARP 协议再次检查 IPv4 地址;如果该地址被其他 dhcp 客户端使用,客户端将向服务器发送一条
DECLINE
消息,并重新启动配置过程*
*## 捕获 DHCPv4 流量
捕获 DHCPv4 流量的命令如下:
-
在 Windows 机器上:
- 启动 Wireshark 捕获。
- 打开命令行提示。
- 键入
ipconfig /renew
并按进入。 - 键入
ipconfig /release
并按键进入。 - 停止 Wireshark 捕获。
-
在 Linux 机器上:
-
启动 Wireshark 捕获。
-
打开命令行提示。
-
调出网络界面:
bash# ifdown eth0:0
-
调出网络界面:
bash$ ifup eth0:0
-
停止 Wireshark 捕获。
-
-
使用 dhclient:
-
启动 Wireshark 捕获。
-
打开命令行提示。
-
捕获一个 DORA 包使用:
bash$dhclient -4 eth0
-
停止捕获。
-
DNA
DNS 代表域名系统。所有机器都使用 DNS 将主机名翻译成 IP 地址。这种机制用于根据查询类型将名称转换为地址(IPv4/IPv6)等属性。
DNS 有三个主要组件:
- 名称空间
- 使该名称空间可用的服务器
- 向服务器查询名称空间的解析器(客户端)
本主题将关注解析器视角,其中客户端向服务器发送查询,服务器应答查询。同一个查询可以有多个答案。
DNS Wireshark 过滤器
Wireshark 的dns
过滤器用于仅显示 DNS 流量,UDP 端口53
用于捕获 DNS 流量。
港口
默认的 DNS 端口是53
,使用 UDP 协议。一些 DNS 系统也使用 TCP 协议。当响应数据大小超过 512 字节时,或者对于诸如区域传输之类的任务,使用 TCP。
资源记录
DNS 系统使用的格式如下:
|
田
|
描述
|
长度
|
Wireshark 过滤器
|
| — | — | — | — |
| 名称 | 所有者姓名 | 可变的 | dns.qry.name == "google.com"
|
| 类型 | 数字形式的资源记录 ( RR )的类型 | Two | dns.qry.type == 1 (A Record Type)``dns.qry.type == 255 (ANY Record Type)``dns.qry.type == 2 (NS name server)``dns.qry.type == 15(MX mail exchange)``dns.qry.type == 28 (AAAA quad A, Ipv6 record Type)
|
| 类 | 类别代码 | Two | dns.qry.class == 0x0001 (IN set to internet)
|
| TTL | 活下去的时间 | four | |
| RDLENGTH | RDATA 字段的八位字节长度 | Two | |
| RDA | 其他特定于 RR 的数据 | 可变的 | |
DNS 流量
在本章中,dig
和nslookup
网络命令用于查询 DNS 服务器。打开示例DNS-Packet.pcap
文件,将显示过滤器设置为dns.qry.type==28
,并检查查询。
在本例中,客户端(192.168.1.101
)要求名称服务器(8.8.4.4
)通过在查询部分设置这些参数来解析ipv6.google.com
:
- 客户端设置记录类型 AAAA 记录
- 客户端设置主机名(
ipv6.google.com
) - 客户端设置类(即
IN (Internet)
) - 名称服务器(
8.8.4.4
)用多个答案响应客户端 ipv6.google.com
是等于ipv6.l.google.com
的规范名称ipv6.l.google.com
has the AAAA address2404:6800:4007:805::200e
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00091.jpeg
用户可以使用流行的dig
或nslookup
网络实用工具命令来查询不同的 DNS 记录类型。在后台使用网络捕获,并观察每个命令的问答部分:
-
查询一个记录类型,用于显示给定主机名的 IPv4 地址:
bash# nslookup google.com bash# dig google.com bash# dig A +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
AXFR
记录类型;AXFR
用于将区域文件从主服务器传输到辅助名称服务器:bash# nslookup -type=axfr google.com 8.8.4.4 bash# dig AXFR +noadditional +noquestion +nocomments +nocmd +nostats +multiline google.com. @8.8.4.4
-
查询
CNAME
记录类型。CNAME
用于设置别名:bash# nslookup -type=cname google.com 8.8.4.4 bash# dig CNAME +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
MX
记录类型;MX
是邮件交换记录:bash# nslookup -type=mx google.com 8.8.4.4 bash# dig MX +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
NS
记录类型;NS
是名称服务器记录:bash# nslookup -type=ns google.com 8.8.4.4 bash# dig NS +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
PTR
记录类型;PTR
是用于反向 DNS 查找的指针:bash# nslookup -type=ptr google.com 8.8.4.4 bash# dig PTR +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
SOA
记录类型。SOA
用于提供域名服务器、电子邮箱等权威信息:bash# nslookup -type=soa google.com 8.8.4.4 bash# dig SOA +noadditional +noquestion +nocomments +nocmd +nostats +multiline google.com. @8.8.4.4
-
查询
TXT
记录类型;这里指的是文字记录:bash# nslookup -type=txt google.com 8.8.4.4 bash# dig TXT +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
-
查询
AAAA
(也称为 quad-A 记录类型);这将显示给定主机名的 IPv6 地址:bash# nslookup -type=aaaa google.com 8.8.4.4 bash# nslookup -type=aaaa ipv6.google.com 8.8.4.4 bash# dig AAAA +noadditional +noquestion +nocomments +nocmd +nostats ipv6.google.com. @8.8.4.4
-
查询
ANY
记录类型;这将返回所有记录类型:bash# nslookup -type=any google.com 8.8.4.4 bash# dig ANY +noadditional +noquestion +nocomments +nocmd +nostats google.com. @8.8.4.4
HTTP
HTTP 是 WWW 中使用的应用层协议。HTTP 支持 HTTP 客户端和 HTTP 服务器之间的通信。示例流量如下图所示。客户端(浏览器或 cURL)创建了一个 HTTP GET
请求,而 HTTP 服务器已经用适当的内容类型进行了响应:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00092.jpeg
HTTP Wireshark 过滤器
使用http
到只显示 HTTP 数据包。使用 TCP 端口80
仅过滤 HTTP 流量;端口80
是默认的 HTTP 端口。
HTTP 用例
下面的例子展示了 Wireshark 可以帮助分析 HTTP 数据包的不同用例。
寻找最快的 HTTP 响应时间
在 Wireshark 中打开文件 http_01.pcap
,找到 HTTP get 请求的 HTTP 响应时间 top:
- 点击编辑 | 首选项|协议 | TCP ,取消勾选允许子指示器重组 TCP 流。这将有助于了解获得实际内容需要多少个延续数据包,并且有助于微调 TCP 参数,例如,设置 TCP 窗口大小以减少延续数据包。
- 在过滤器栏中,应用
http
过滤器并从http.response.code == 200 HTTP OK
包中添加http.time
作为一列。 - Click on the Time since request column and make it in descending order. Find the request frame and click on the link.https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00093.jpeg
基于 HTTP 方法查找数据包
使用 Wireshark 的http.request.method
显示用于分析的数据包。例如,下表描述了如何应用此过滤器:
|
HTTP 方法
|
意义
|
Wireshark 过滤器
|
| — | — | — |
| GET
| 获取指定的资源示例:GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
| http.request.method=="GET"
|
| POST
| 向指定的资源提交要处理的数据 | http.request.method=="POST"
|
| PUT
| 上传指定 URI 的表示形式 | http.request.method=="PUT"
|
| DELETE
| 删除指定的资源/实体 | http.request.method=="DELETE"
|
| OPTIONS
| 返回服务器支持的 HTTP 方法 | http.request.method=="OPTIONS"
|
| CONNECT
| 将请求连接转换成透明的 TCP/IP 隧道 | http.request.method=="CONNECT"
|
在表单帖子中查找敏感信息
如果表单包含密码等敏感信息,Wireshark 可以轻易泄露,因为 HTTP 是一种不安全的网络数据传输方式。
打开HTTP_FORM_POST.pcap
文件并过滤流量,仅显示请求方法POST
并找到密码表单项,如以下屏幕截图所示:
https://github.com/OpenDocCN/freelearn-kali-pt2-zh/raw/master/docs/pkt-anal-ws/img/00094.jpeg
使用 HTTP 状态码
HTTP 响应的第一行包含状态代码。使用 Wireshark 过滤器http.response.code
,根据状态代码显示数据包。这将有助于调试 HTTP 客户端-服务器交互:
|
类型
|
密码
|
意义
|
HTTP Wireshark 过滤器
|
| — | — | — | — |
| 信息–1xx | One hundred | 继续 | http.response.code == 100
|
| One hundred and one | 交换协议 | http.response.code == 101
|
| 成功–2xx 出发地:200 号公路收件人:206 | Two hundred | 好 | http.response.code == 200
|
| Two hundred and one | 创造 | http.response.code == 201
|
| 重定向–3xx 出发地:300 号公路收件人:307 | Three hundred | 多选 | http.response.code == 300
|
| Three hundred and one | 永久移动 | http.response.code == 301
|
| 客户端错误–4xx 出发地:400 号公路收件人:417 | four hundred | 错误的请求 | http.response.code == 400
|
| Four hundred and one | 未经授权的 | http.response.code == 401
|
| 服务器错误–5xx 从—500 至- 505 | Five hundred | 内部服务器错误 | http.response.code == 500
|
| Five hundred and one | 未实施 | http.response.code == 501
|
参考文献
HTTP 协议:
- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- https://wiki.wireshark.org/Hyper_Text_Transfer_Protocol
DNS 协议:
- https://en . Wikipedia . org/wiki/Domain _ Name _ System # Protocol _ transport
- https://www.ietf.org/rfc/rfc1035.txt
DHCP/BOOT 协议:
- https://tools.ietf.org/html/rfc2131
- http://linux.die.net/man/8/dhclient
- http://www . iana . org/assignments/BOOTP-DHCP-parameters/BOOTP-DHCP-parameters . XHTML
- https://goo.gl/snUXkp
DHCPv6 协议:
- http://www . iana . org/assignments/DHCP V6-parameters/DHCP V6-parameters . XHTML
- https://tools.ietf.org/html/rfc3315
- https://en.wikipedia.org/wiki/DHCPv6
总结
在本章中,我们学习了 Wireshark 如何帮助我们分析应用层协议,如 DHCPv6、DHCP、DNS 和 HTTP。我们还学习了如何在网络上模拟这些流量。
在下一章,我们将学习更多关于无线嗅探的知识。*