TCP Analysis Flags 之 TCP ZeroWindowProbe

news2024/11/23 23:43:53

前言

默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可以通过 “Analyze TCP sequence numbers” TCP 解析首选项启用或禁用此功能。

TCP 分析展示

在 TCP 分析中和 TCP 零窗口相关的实际上有三种信息,分别是:TCP ZeroWindowTCP ZeroWindowProbeTCP ZeroWindowProbeAck 。实际运行环境中,有时是单独出现的,譬如 TCP ZeroWindow ,有时是一起出现的,也就是出现了零窗口,之后就会出现需要为恢复窗口而进行的零窗口探测和零窗口探测确认。

在数据包文件中进行 TCP 分析时,关于 “TCP ZeroWindowProbe”、“TCP ZeroWindowProbeAck” 一般是如下显示的,包括:

  1. Packet List 窗口中的 Info 信息列,以 [TCP ZeroWindowProbe]、[TCP ZeroWindowProbeAck] 黑底红字进行标注;
  2. Packet Details 窗口中的 TCP 协议树下,在 [SEQ/ACK analysis] -> [TCP Analysis Flags] 中定义该 TCP 数据包的分析说明。

TCP ZeroWindowProbe 和 ZeroWindowProbeAck 定义

实际在 TCP 分析中,关于 TCP ZeroWindowProbe 和 ZeroWindowProbeAck 相关的定义也相对简单,主要说明如下:

  1. TCP ZeroWindowProbe

当满足以下多个条件时设置,包括:

  • 当 Seq Num 等于之前下一个期望的 Seq Num
  • TCP 段大小为 1
  • 反方向最后一次看到的接收窗口大小为零时设置

影响 Fast RetransmissionOut-Of-OrderRetransmission

Set when the sequence number is equal to the next expected sequence number, the segment size is one, and last-seen window size in the reverse direction was zero.

If the single data byte from a Zero Window Probe is dropped by the receiver (not ACKed), then a subsequent segment should not be flagged as retransmission if all of the following conditions are true for that segment: * The segment size is larger than one. * The next expected sequence number is one less than the current sequence number.

This affects “Fast Retransmission”, “Out-Of-Order”, or “Retransmission”.

具体的代码如下,总的来说这段代码的作用是检测零窗口探测包,并对其做出适当的标记,以便 Wireshark 进行后续的分析和显示。 主要检测以下三个条件,如果都满足,则认为是一个零窗口探测数据包。

  • 检查 TCP 段长度是否为 1 字节;
  • 检查 Seq Num 是否等于之前下一个期望的 Seq Num;
  • 检查反方向之前的接收窗口大小是否为 0。
    /* ZERO WINDOW PROBE
     * it is a zero window probe if
     *  the sequence number is the next expected one
     *  the window in the other direction is 0
     *  the segment is exactly 1 byte
     */
    if( seglen==1
    &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
    &&  tcpd->rev->window==0 ) {
        if(!tcpd->ta) {
            tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
        }
        tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
        goto finished_fwd;
    }
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. 关于零窗口探测数据包的定义和说明,段大小为 1 字节,但在 linux 下实测是 0 字节,之后展开说明。
  1. TCP ZeroWindowProbeAck

当满足以下多个条件时设置,包括:

  • TCP 段大小为 0
  • 接收窗口大小为 0
  • Seq Num 是否等于之前下一个期望的 Seq Num
  • Ack Num 等于之前的 LastAck Num
  • 反方向之前数据包是一个零窗口探针

替代 TCP Dup ACK

Set when the all of the following are true:

The segment size is zero.
The window size is zero.
The sequence number is equal to the next expected sequence number.
The acknowledgment number is equal to the last-seen acknowledgment number.
The last-seen packet in the reverse direction was a zero window probe.

Supersedes “TCP Dup ACK”.

具体的代码如下,总的来说这段代码的作用是用于检测零窗口探测的 ACK 包,并对其进行适当的标记和处理,以便 Wireshark 能够正确分析和显示 TCP 流量控制过程中的重要信息。代码逻辑如下,如果所有条件都满足,则认为该 ACK 数据包是对零窗口探测包的响应,包括:

  • 检查 TCP 段长度是否为 0;
  • 检查接收窗口大小是否为 0;
  • 检查接收窗口大小与同方向之前接收窗口大小是否相同;
  • 检查 Seq Num 是否等于同方向之前下一个期望的 Seq Num;
  • 检查 ACK Num 是否等于同方向之前的 LastACK Num,或者是同方向之前的 LastACK Num+1;
  • 检查反方向之前数据包是否是零窗口探测包;
  • 检查当前数据包是否不是 SYN/FIN/RST 数据包。
    /* ZERO WINDOW PROBE ACK
     * It is a zerowindowprobe ack if it repeats the previous ACK and if
     * the last segment in the reverse direction was a zerowindowprobe
     * It also repeats the previous zero window indication
     */
    if( seglen==0
    &&  window==0
    &&  window==tcpd->fwd->window
    &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
    &&  (ack==tcpd->fwd->tcp_analyze_seq_info->lastack || EQ_SEQ(ack,tcpd->fwd->tcp_analyze_seq_info->lastack+1))
    && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
    &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
        if(!tcpd->ta) {
            tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
        }
        tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;

        /* Some receivers consume that extra byte brought in the PROBE,
         * but it was too early to know that during the WINDOW PROBE analysis.
         * Do it now by moving the rev nextseq & maxseqtobeacked.
         * See issue 10745.
         */
        if(EQ_SEQ(ack,tcpd->fwd->tcp_analyze_seq_info->lastack+1)) {
            tcpd->rev->tcp_analyze_seq_info->nextseq=ack;
            tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked=ack;
        }
        goto finished_fwd;
    }
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. lastack,定义为 Last seen ack for the reverse flow。
  3. 相对于文档介绍,代码中多了一些判断条件,包括像是与之前接收窗口的比较(是否都为 0),Ack Num 等于之前 Ack Num+1的场景。

Packetdrill 示例

根据上述 TCP ZeroWindowProbeTCP ZeroWindowProbeAck 定义和代码说明,起初我认为 packetdrill 是比较容易模拟出来的,只要满足当网络中没有发送且未确认的数据包,且本端有待发送的数据包时,则启动零窗口探测定时器,在超时后发出零窗口探测包,段大小为 1 字节,但是实际按以下 packetdrill 代码模拟后,测试出来的零窗口探测包,段大小为 0 字节,这样在 Wireshark 中会识别为 TCP Keep-Alive 数据包,而不是 TCP ZeroWindowProbe 数据包。

# cat tcp_zero_window_probe.pkt 
0   socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0  setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0  bind(3, ..., ...) = 0
+0  listen(3, 1) = 0

+0  < S 0:0(0) win 1000 <mss 1460>
+0  > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 1000
+0 accept(3, ..., ...) = 4

+.1 write(4, ..., 1000) = 1000
+0 > P. 1:1001(1000) ack 1
+0.01 < . 1:1(0) ack 1001 win 0

+.1 write(4, ..., 1000) = 1000

+0 `sleep 100000`
# 

以上产生了一个疑问,对于 TCP 零窗口探测数据包,它的数据段是 1 字节还是 0 字节?还是两者都可以?
至少说绝大多数的资料上,都写的是 1 字节,包括 RFC9293 中关于 Zero-Window Probing 的一段说明,截取如下:

The sending TCP peer must regularly transmit at least one octet of new data (if available), or retransmit to the receiving TCP peer even if the send window is zero, in order to "probe" the window.

而且 Wireshark TCP 分析标志定义和源码中也是如此:

Set when the sequence number is equal to the next expected sequence number, the segment size is one, and last-seen window size in the reverse direction was zero.

但是在 Linux (5.15.0) 通过 packetdrill 测试的结果却是 0 字节,因此会被 Wirehshark 识别为 TCP Keep-Alive 数据包,简单翻了下源码,感觉确实是发送序号为 snd_una - 1、长度为 0 的 ACK 包作为探测包,以下少数资料也提到这一点:

https://blog.csdn.net/sinat_20184565/article/details/105691191

https://blog.csdn.net/zhangskd/article/details/44571323

https://www.cnblogs.com/lshs/p/6038654.html

https://blog.csdn.net/weixin_45537413/article/details/114069445

http://www.tcpipguide.com/free/t_TCPWindowManagementIssues-3.htm

其中 TCPIPGUIDE 中的说明:The probe segment can contain either zero or one byte of data, even when the window is closed.

现阶段我的答案是 Windows 系统是 1 字节,Linux 系统(可能是所有版本又或是某个版本之后)是 0 字节。

至少我觉得可以在某个时间提交一个 Issue,和 Wireshark 开发者探讨下,是否能改进相关的判断逻辑。

实例

关于 TCP ZeroWindowProbeTCP ZeroWindowProbeAck 的实例,依赖于 TCP ZeroWindow 的出现,实际日常抓包中并不是经常会看到,但如果看到了,则代表着本端接收窗口为 0 ,意味着本端因性能或容量等问题而无法接收数据,因此通知发送方暂停发送数据,而发送方满足一定条件,启动零窗口探测定时器,在超时后发出零窗口探测包 TCP ZeroWindowProbe ,接收端根据窗口是否恢复的情况回复 TCP ZeroWindowProbeAck 或者 TCP Window Update

  1. TCP ZeroWindow + TCP ZeroWindowProbe + TCP Window Update

一种零窗口情景,接收端出现 Win 为 0 的情形,发送 TCP ZeroWindow 通知,发送端在经过一段时间后发出 TCP ZeroWindowProbe 数据包,但接收端收到探测后,由于已经打开窗口,因此直接回复 TCP Window Update 数据包。

首先服务器端 No.10 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow],之后 286ms 客户端发送了 No.11 [TCP ZeroWindowProbe] 用于确认服务器端接收窗口是否恢复,服务器紧接着回复确认 No.12,表示窗口已恢复 Win 1420,标识为 [TCP Window Update] 数据包。

  1. TCP Window Full + TCP ZeroWindow + TCP ZeroWindowProbe + TCP ZeroWindowProbeAck + TCP Window Update

大满贯场景,覆盖了 5 种 TCP 分析标志。首先客户端发送数据,发现服务器接收窗口满了,则在 No.4 和 No.6 上标识 [TCP Window Full] ,此时服务器端 No.7 因为 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow],之后陷入等待,大概 2 秒+后,客户端发送了 No.8 [TCP ZeroWindowProbe] 用于确认服务器端接收窗口是否恢复,服务器紧接着回复确认 No.9,表示仍处于零窗口未恢复,标识为 [TCP ZeroWindowProbeAck] + [TCP ZeroWindow] ,又再过了 300ms 后,服务器端发送 No.10 Win 此时更新为 14600,表示接收窗口已恢复,标识成 [TCP Window Update] ,至此完成一次完整的零窗口出现、探测及恢复过程。

类似的场景同样如下

  1. Keep-Alive 零窗口探测特例

在上述 packetdrill 示例中已经提及,TCP 零窗口探测包 0 字节,在 Wireshark 会识别成 TCP Keep-Alive 数据包的特殊示例。

首先服务器端发送数据,发现客户端接收窗口满了,则在 No.5 上标识 [TCP Window Full] ,此时客户端 No.6 因为 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow] ,之后因为当网络中没有发送且未确认的数据包,且服务器端有待发送的数据包时,启动了零窗口探测定时器,在超时后发出零窗口探测包,Seq Num 回退 1 为 1000,且段大小为 0 字节,标识成 [TCP Keep-Alive] 。之后因为未模拟客户端回复 ACK 数据包,所以服务器端在未收到确认的情况下,不断超时重传零窗口探测数据包。

总结

套用以前总结的一句话,不要迷信 Wireshark,虽是神器,但不是万能的,只有学到手的东西,才是真正属于自己的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2188441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是沉默成本?超详细+通俗易懂版

沉默成本是一个在会计学、金融学以及经济学中常用的概念&#xff0c;但更常见的表述是沉没成本&#xff08;Sunk Cost&#xff09;。沉没成本指的是已经发生且无法收回的成本&#xff0c;这些成本与当前的决策无关&#xff0c;但往往会影响人们的决策过程。以下是对沉没成本的详…

【MySQL】Ubuntu环境下MySQL的安装与卸载

目录 1.MYSQL的安装 2.MYSQL的卸载 1.MYSQL的安装 首先我们要看看我们环境里面有没有已经安装好的MySQL 我们发现是默认是没有的。 我们还可以通过下面这个命令来确认有没有mysql的安装包 首先我们得知道我们当前的系统版本是什么 lsb_release -a 我们在找apt源的时候&a…

vulnhub-unknowndevice64 2靶机

vulnhub&#xff1a;https://www.vulnhub.com/entry/unknowndevice64-2,297/ 导入靶机&#xff0c;放在kali同网段&#xff0c;扫描 靶机在192.168.81.9&#xff0c;扫描端口 啥啊这都是&#xff0c;详细扫描一下 5555是adb&#xff0c;6465是ssh&#xff0c;12345看样子应该是…

Python 工具库每日推荐 【BeautifulSoup】

文章目录 引言Python工具库的重要性今日推荐:BeautifulSoup工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例获取 BeautifulSoup 官网文档首页的标题与所有图片案例分析扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScript 设计模式 专栏…

医疗应急三维电子沙盘系统

一、主要硬件功能指标要求&#xff1a; 1.沙盘尺寸≥98寸&#xff1b;分辨率&#xff1a;≥19201080&#xff1b;亮度500cd/m2&#xff1b;对比度4000&#xff1a;1&#xff1b;显示模式16&#xff1a;9&#xff1b;电源&#xff1a;100VAC&#xff5e;240VAC(50/60Hz)&#xf…

如何在 MySQL 中处理大量的 DELETE 操作

在 MySQL 数据库的使用过程中&#xff0c;我们有时会面临需要处理大量 DELETE 操作的情况。如果处理不当&#xff0c;可能会导致数据库性能下降、锁等待甚至系统崩溃。本文将介绍一些在 MySQL 中处理大量 DELETE 操作的方法。 一、问题背景 当需要删除大量数据时&#xff0c;…

手写mybatis之实现映射器的注册和使用

前言 其实对于解决这类复杂的项目问题&#xff0c;核心在于要将主干问题点缩小&#xff0c;具体的手段包括&#xff1a;分治、抽象和知识。运用设计模式和设计原则等相关知识&#xff0c;把问题空间合理切割为若干子问题&#xff0c;问题越小也就越容易理解和处理。就像你可以把…

【论文阅读】Segment Anything Model for Road Network Graph Extraction

【论文阅读】Segment Anything Model for Road Network Graph Extraction (CVPRW 2024) Paper链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2024W/SG2RL/html/Hetang_Segment_Anything_Model_for_Road_Network_Graph_Extraction_CVPRW_2024_paper.html 文章目录…

基于SSM医疗信息管理系统(源码+定制+参考)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

vue文件的认识

1.package.json 项目包文件 里面包含许多可以在命令提示符中运行的命令&#xff0c;这里使用vue3创建的项目&#xff0c;所以dev是“vite”。 2.main.js 整个项目的入口文件&#xff0c;createApp创建应用实例 createApp(App).mount(#app) 这句话意思是以App作为参数生成一…

ElasticSearch备考 -- Search scroll

一、题目 Search for all documents in all indices As above, but use the scroll API to return the first 100 results while keeping the search context alive for 2 minutes Use the scroll id included in the response to the previous query and retrieve the next ba…

启用vnc访问Dell 服务器IDRAC 7虚拟控制台

Dell IDRAC 7 版本太老&#xff0c;SSL证书过期&#xff0c;IDRAC的Java和本地远程虚拟机控制台访问不了&#xff0c;怎么办&#xff1f; 可以启用vnc访问IDRAC 虚拟控制台

Vue2如何在网页实现文字的逐个显现

目录 Blue留言&#xff1a; 效果图&#xff1a; 实现思路&#xff1a; 代码&#xff1a; 1、空字符串与需渲染的字符串的定义 2、vue的插值表达式 3、函数 4、mounted()函数调用 结语&#xff1a; Blue留言&#xff1a; 在国庆前夕&#xff0c;突发奇想&#xff0c;我想…

SAP HCM 自定义累计期间

需求是按3月&#xff5e;8月&#xff0c;9月&#xff5e;次年2月&#xff0c;做为累计期间&#xff0c;怎么处理&#xff1f;

微信小程序hbuilderx+uniapp+Android 新农村综合风貌旅游展示平台

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 小程序端…

5G NR coreset 简介

文章目录 5G 为何引入CORESETCORESET介绍CORESET 分类 5G 为何引入CORESET 在LTE系统中&#xff0c;PDCCH频域占据整个带宽&#xff0c;始于占据每个RB的前1~3个OFDM 符号&#xff0c;这种情况下&#xff0c;UE 只需知道PDCCH 所占据的OFDM 符号数&#xff0c;就可以确定PDCCH…

内存对齐

内存对齐的基本规则是&#xff1a;只能在自己所占字节的整数倍的内存地址上存放&#xff08;结构体也是如此&#xff09;。 假如定义一下变量&#xff1a; 对应的存储格式为&#xff1a; 由于变量C占四个字节&#xff0c;所以从12开始。 对于整个结构体而言&#xff1a;结构体…

【Web】portswigger 服务端原型污染 labs 全解

目录 服务端原型污染 为什么服务器端原型污染更难检测&#xff1f; 通过受污染的属性反射检测服务器端原型污染 lab1:通过服务器端原型污染进行权限提升 无需污染属性反射即可检测服务器端原型污染 状态代码覆盖 JSON 空格覆盖 字符集覆盖 lab2:检测没有污染属性反射的…

Pikachu-xss防范措施 - href输出 js输出

总体原则&#xff1a; 输入做过滤&#xff0c;输出做转义 过滤&#xff1a;根据业务需要进行过滤&#xff0c;如&#xff1a;输入点要求输入手机号&#xff0c;则只允许输入手机号格式的数字&#xff1b; 转义&#xff1a;所有输出到前端的数据&#xff0c;都根据输出点进行转…

银河麒麟V10如何快速进入单用户模式?

银河麒麟V10如何快速进入单用户模式&#xff1f; 1. 进入GRUB菜单2. 编辑启动项3. 登录系统4. 修改启动参数5. 退出单用户模式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 银河麒麟高级服务器操作系统V10在系统维护或故障排查时&#xf…