TcpIP协议,HTTP,DNS 实战:基于wireshark与BurpSuite抓包分析


使用 wireshark 前的基本配置

磨刀不误砍柴工。为了高效率的利用 wireshark 来帮助我们分析,学习网络协议,以及故障排除,需要对其进行一些使用前配置,大致内容如下:


1。将数据包摘要列表(packet list)中的“time”列的精度调整为 1 毫秒。

默认情况下,wireshark 的时间显示精度为 1 纳秒,但是在现实环境中通常用不到如此高的精度,一般用于评估站点响应速度,用户体验的性能指标,精确到毫秒级别就足够了,而且纳秒会多显示小数点后 6 位数字,造成数据包摘要列表中的显示空间的浪费。具体设置方法如下图:


wKiom1VW9NiBsQloAA7Oc5dOzVY457.jpg

wKioL1VW93mxTHZIAAJHi4-IkzM493.jpg


2。根据应用场景选择时间列的显示格式。默认情况下,以抓取到的第一个数据包的时间为参考点,后续的数据包的抓取时间都是相对开始抓包(第一个)的时点计算的。但是在某些场景中,需要将显示格式调整为:与上一个抓取到的数据包的时间差,也就是相邻2个数据包的抓包时间间隔。

我们知道,某些网络应用,如即时通信,会议软件的视频,音频流量等,对于数据包的连续发送或接收时间间隔,非常敏感,如果相邻2个或多个包的间隔时间太长,就会造成应用的画面和声音延迟,一个更明显的例子是网络游戏的“卡”现象,由于收发包的间隔过长导致声音与画面的不一致和连续性问题。(通常与两端通信链路的负载和其中路由器的负载过高,导致丢包而引发的 TCP 分段重传有关)

这个时候,显示时间间隔就非常有用,可以对当前网络的稳定性,流畅性进行快速的检视,具体配置方法如下图:


wKioL1VW_yrx6nJPAA52oJnW2Uo124.jpg


wKiom1VXAkrAt0BjAATvZduqs3E921.jpg



3。修改并导出 wireshark 的默认数据包着色识别规则。通过数据包着色功能,用户可以迅速定位感兴趣的数据包分析,但是默认的着色规则太复杂,导致启用色彩识别时,一个包列表中显示“五颜六色”的信息,分散了我们的注意力,通常情况,我们仅对一种或两种类型的数据包感兴趣,或者进一步讲,我们每次只需要标识一种或两种类型的数据包颜色,这就需要修改其默认着色规则,具体配置方法参考下图:

依序选择菜单栏的“View”,“Coloring Rules”,打开配色规则对话框:


wKioL1VXWN-RfLAAAA9f9o8sbWM490.jpg

wKioL1VXW0rzNPp3ABKlaRKf6NI804.jpg



4。自定义数据包列表的显示列。默认的显示列从左至右依序为:数据帧编号,抓取时间,源地址,目标地址,协议,数据包(帧)长度,摘要信息。

在实战场景中,这些列提供的信息可能不够,例如,我想要快速浏览每个包的 IP 分组头部的生存期(TTL)字段值,而且不用在每个包的详细结构窗口(packet details)中查找该字段,以便节省时间,可以按照下图操作:

依序选择菜单栏的“Edit”,“Preferences”,打开首选项对话框:


wKioL1VXYwbzjpo1AAggqkBFO8M584.jpg

wKioL1VXZKCwb7RIAAwwm_Wgd2Y465.jpg


5。根据实际需求配置 wireshark 的名称解析功能。

依序选择菜单栏的“Edit”,“Preferences”,切换到首选项对话框中的“Name Resolution”标签,参考下图解说进行配置:


wKioL1VYLXjiejPTAAvBCaAF5dU530.jpg


通常只需要保持默认的不解析链路层,网络层地址以及传输层端口号即可,但是有些时候就需要开启相应的解析功能,还是那句老话:具体情况具体分析。上图中没有解释到的名称解析剩余的配置选项部分,各位可以自行研究。


6。隐藏 wireshark 主用户界面的数据包字节窗口(Packet Btyes)

默认的用户界面布局中,窗口被分隔成为3部分:数据包列表,数据包结构(详情),以及数据包字节,后者以16进制的字节显示数据包内容,通常是我们不必关心的,除非你有某种特殊的需求要修改原始的数据包;否则可以隐藏字节窗口,释放额外的显示空间。依序选择“View”,取消勾选“Packet Bytes”即可。


7。wireshark 中与 IPv4 协议相关的配置参数

配置各种协议的参数,实际上就是改变 wireshark 对该协议数据包的“捕获”与“呈现”方式。要配置 IPv4 协议,依序选择菜单栏的

“Edit”,“Preferences”,展开首选项对话框中的“Protocols”标签,定位到“IPv4”子标签。参考下图解说进行配置:


wKioL1VYPq2SM2D9AAldBZHhuac772.jpg


下面来比较一下,对于同一个数据包的 IP 分组头部的 ToS 字段,wireshark 用旧的服务质量标准(服务类型)与用新的服务质量标准(即差异化/区分 服务)解析之间的区别,可以看出,两者仅是对这个占一字节的头部字段中,每个比特位的解释不同而已:


wKiom1VYR2mjb-d7AAN5jvu29yk330.jpg


wKiom1VYR33BRE1JAAQjEogHWM0794.jpg



8。wireshark 中与 TCP 协议相关的配置参数

要配置 TCP 协议,依序选择菜单栏的

“Edit”,“Preferences”,展开首选项对话框中的“Protocols”标签,定位到“TCP”子标签。参考下图解说进行配置:

(由于 TCP 协议规范相当复杂,而且各种操作系统有其不同的实现,下面的每个选项不一定在所有系统上都会产生描述中预期的结果,并且这里仅对一些重要,常见的 TCP 协议特性相关的选项配置进行说明,剩余的各位可以自行研究,理想情况下,在阅读完《TCP/IP详解》丛书后,应该能了解下图中绝大多数的配置参数的含义)


wKiom1VZlobiPLMSAA1vgtxz-p8073.jpg

下面通过图片解析上图中的一些配置选项的含义,首先是硬件校验和,它与网卡硬件驱动程序提供的配置接口有关,在 windows 中如下所示:


wKioL1VZmo_Bi5XtAAbHvWmYi6s938.jpg

通过 wireshark 支持的显示过滤表达式:

tcp.checksum_bad == 1

可以仅显示那些 TCP 校验和错误(由 wireshark 或网卡验证的)的数据包:

wKioL1VZnnDjawYpABT5w_QZj-0698.jpg


接着,让我们分析“Analyze TCP sequence numbers”选项起到的作用:


wKiom1VZoBiAWajXAA47Qoznuxo179.jpg


wKioL1VZpA7hHFo-AA4w__dg3OM159.jpg


wKiom1VZo07CCMzQAAOTk7OQoXc877.jpg

wKioL1VZpS_CgnoMAAKTLy51ADU519.jpgwKiom1VZpMjSmQw-AANvhuf4_gQ590.jpg


再来,我们比较从 0 开始的 TCP 相对序号(由 wireshark “改写”的)与随机产生的绝对序号(由操作系统协议栈填充的真实序号)之间的区别:


wKiom1VZq27iu1PEABLs92omrkU442.jpg


wKiom1VZrdywYhb2ABLlvGsI44U156.jpg


也就是说,使用相对序号能够让我们更直观地看出 TCP 序号(在整个 TCP 会话数据流中)起到的作用。

最后,解释 TCP 协议中的一个很重要的概念:窗口缩放。

在 TCP 三次握手期间,双方会通告自己的接收窗口大小(rwnd),以字节为单位,这通常是操作系统的协议栈的接收缓冲区的大小。rwnd 用于 TCP 的流量控制,简言之,发送方每次(并行)发送的数据不能超过接收方向其通告的 rwnd 值,该值是动态变化的,随着双方每次发送的确认分段(ACK)而更新,这个过程将贯穿整个 TCP 会话的生命周期,这样就可以实现动态调整双方发送数据的速度:假设某一方的应用进程迟迟不读取位于内核接收缓冲区的数据,那么在本次发送 ACK 的同时,会将 rwnd 的值调低一些并通告对方,后者就会按照更新后的 rwnd 为上限来发送数据;而等到应用取走缓冲区的数据后,就可以更新一个较大的 rwnd 值并在相应的 ACK 中通告对方。

在实际场景中,有时双方在握手期间相互通告的初始 rwnd 值都过于“保守”,不能最大程度利用链路的峰值带宽,常见的初始值为 8192 字节,这意味着在通信的早期阶段,双方同时并行发送的数据不能超过 8KBytes,假设往返时间为 100 毫秒,那么每秒发送的数据不超过 80KBytes,这相当于每秒发送不超过 53个 TCP 分段(一次“往”需要100毫秒,即每100毫秒一次,并行发送最多5个TCP 分段),再假设链路带宽为 10MBits/s = 1.25MBytes/s ,也就是“理论上”该链路可以承载每秒 1.25MBytes 的数据吞吐量(或者说可以支持的 rwnd 上限为每 100毫秒 125KBytes,支持每100毫秒一次并行发送最多83个 TCP 分段),而实际的带宽只有 80KBytes/s ,这就造成带宽利用率偏低(6.4%)。

通过前面简单的计算我们发现,如果不把 rwnd 增大到 125KBytes,很难充分利用

10M 带宽的链路,因为即便通过 TCP 慢启动效应逐渐增大初始拥塞窗口(每次能够并行发送的 TCP 分段上限),可以从最初的每100毫秒一次并行5个到达每100毫秒一次并行83个的上限,但由于原始的 TCP 规范限制 rwnd 最大为 65KBytes(rwnd 字段在 TCP 头部中占2字节,即16位,2的16幂为65536),实际最多也只能每100毫秒一次并行43个 TCP 分段(这还需要双方“懂得”将 rwnd 增大到 65KBytes),浪费了50%的带宽资源!

为了解决上述“理论带宽”与“实际带宽”不匹配的窘境,在 RFC 1323 标准中,引入了窗口缩放这个概念,窗口缩放是在 TCP 头部的选项中,占3字节的字段,其中一个16进制字节用于表示“缩放因子”,取值从 00(当前 rwnd *2的0幂 = 当前 rwnd *1 = 不缩放)~0e(当前 rwnd * 2的14幂 = 当前 rwnd * 16384)

由于 rwnd 最大取值为 65536 字节,而缩放因子最大为 16384 倍,因此该标准支持的最大 rwnd 值为:65536 * 16384 = 1073741824 字节,即 1GBytes,这足够有效地利用千兆(吉比特)带宽的光纤链路了!

另外,该标准规定了窗口缩放因子必须在 TCP 三次握手过程中协商完成,此后都不许再更改协议好的值。通过窗口缩放,要充分利用前面 10M 链路的带宽,以初始的 rwnd = 8KBytes 为例,仅仅需要将缩放因子设置为16进制的字节“04”即可

(2的4幂 = 16,8 * 16 = 128KBytes,已经超过了 125KBytes)

有了上面的基础知识后,再来回顾 wireshark 中,与 TCP 窗口缩放相关的配置参数,就能够轻松理解了:


wKiom1VaIX2jqkatAAkou2rvOjA925.jpg


wKiom1VaKmaRfXVyABMyzE08OUE862.jpg


wKioL1VaLq_w9eXjAA_twiovPYE112.jpg


最后还有一个 TCP 配置选项“calculate conversation timestamps”

它的作用是计算每个 TCP 会话中的每一帧(或 TCP 分段)相对于第一帧以及前一帧的时间戳(差),这对于检测时间敏感型 TCP 应用,也就是用户体验度要求高的应用的性能会有帮助,效果如下所示:


wKioL1Va4ELA7FKxAAOpZLL3frg055.jpg


剩余的4个 TCP 相关的配置选项各位可以自行研究,推荐先读完tcpip详解后再来理解效果会更好。


《关于TCP超时与重传》


TCP 超时与重传中,最重要的部分就是对一个给定连接的往返时间(RTT)的测量。由于路由器和网络流量均会变化,因此我们认为这个 RTT 可能经常会发生变化,TCP 应该跟踪这些变化并相应地改变其重传超时时间(RTO,Retransmission TimeOut)。

发送报文段时会启动RTT计时器,当接收到该报文段对应的ACK时,停止计时器,从而计算出RTT,然后根据这个RTT计算出TCP RTO,发送下一个报文段时,重传计时器将根据最新的 TCP RTO 值,在超过该值表示的时间后还没有接收到ACK,则重传报文段。

实例解析:


wKioL1VqxiuxpRlYAAksKXqEXmM353.jpg