4

在用tcpdump抓包时,发现前面两次握手的seq和ack能对应起来,但是第三次由客户端发起的确认ack值为1,熟悉tcp三次握手的都知道,ack的值是对方的seq+1,第三次握手的ack值不应该是1,测试抓了各种端口的tcp包发现都是这样,难道是因为tcp协议改动了?

tcpdump抓包复现

直接tcpdump命令即可,如果更详细点的信息,可加-v不过跟当前复现内容没有太多关系

14:29:06.049398 IP 100.116.251.137.53686 > 10.0.0.15.81: Flags [S], seq 413886776, win 29130, options [mss 1942,sackOK,TS val 2047175890 ecr 0,nop,wscale 9], length 0
14:29:06.049406 IP 10.0.0.15.81 > 100.116.251.137.53686: Flags [S.], seq 1511062036, ack 413886777, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
14:29:06.049711 IP 100.116.251.137.53686 > 10.0.0.15.81: Flags [.], ack 1, win 57, length 0
14:29:06.050075 IP 100.116.251.137.53686 > 10.0.0.15.81: Flags [P.], seq 1:20, ack 1, win 57, length 19
14:29:06.050087 IP 10.0.0.15.81 > 100.116.251.137.53686: Flags [.], ack 20, win 115, length 0
14:29:06.050107 IP 10.0.0.15.81 > 100.116.251.137.53686: Flags [P.], seq 1:184, ack 20, win 115, length 183
14:29:06.050118 IP 10.0.0.15.81 > 100.116.251.137.53686: Flags [F.], seq 184, ack 20, win 115, length 0

第一行100.116.251.137端口53686向10.0.0.15端口81发起了SYN主动连接的请求,seq为413886776

第二行10.0.0.15.81端口81向100.116.251.137端口53686发起了SYN请求,seq为1511062036,注意ack是413886776+1=413886777
那么以上两次都没什么问题,正常的握手

问题出在第三行,本来按照三次握手,最后确认,ack应该是第二次握手的seq+1,也就是1511062036+1=1511062037,这才是正确的ack,但tcpdump抓包的显示是1

利用wireshark分析

于是将tcp包抓到本地,利用wireshark来分析下看看能否找到答案

抓包命令

tcpdump -w test.cap

clipboard.png
上面这张图就是三次握手的包在wireshark,前三行封包就是三次握手,发现在wireshark里面seq从0开始,其实seq也不是0,可以看下面的具体值。不过第三次握手依然显示ack=1

通过wireshark逐行分析

第一行
clipboard.png
seq:82 dc ee f2
ack:0
第二行
seq
clipboard.png

ack
clipboard.png
seq:7c d5 55 21
ack:82 dc ee f3
ack的值刚好是第一行的seq+1

第三行
clipboard.png
ack:7c d5 55 22

结语
看到这里就明白了,第三次握手的ack虽然在tcpdump显示为1,但是值是第二行的seq+1
因此不是tcp三次握手协议变了,应该是tcpdump简化了显示

更正
又翻下书,多了些理解,上面的没有什么问题,确实是tcpdump简化了显示,注意看这几张图的seq和ack
Sequence number: 1 (relative sequece number)
Acknownledgment number: 1 (relative ack number)

tcpdump抓的包除了SYN标记的包外,seq 和 ack都是relative(相对)显示的,比如确认,就是ack=1,这样做的目的是方便查看

至于为什么是1,这里涉及到一个大写的ACK,这个ACK标记是TCP首部的一部分,是确认序列号的标识,只有ACK被设置为1时,,确认序号字段才有效

而连接一旦建立,这个字段会被设置(在第二次握手及之后),ACK标记被设置为1,因此,第三次握手ack数值为1,也是说明这是一个确认ack

如果想显示绝对数值,在使用tcpdump命令时加上-S即可

tcpdump -S -nn
16:24:20.576993 IP 100.116.200.126.45424 > 10.29.64.142.4433: Flags [S], seq 4026609082, win 65535, options [nop,nop,TS val 3774652920 ecr 0,mss 1718,wscale 3,nop,sackOK,eol], length 0
16:24:20.577011 IP 10.29.64.142.4433 > 100.116.200.126.45424: Flags [S.], seq 2677560139, ack 4026609083, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
16:24:20.577123 IP 100.116.200.126.45424 > 10.29.64.142.4433: Flags [.], ack 2677560140, win 16535, options [nop,nop,sack 1 {2677560139:2677560140}], length 0


青叶
452 声望43 粉丝

引用和评论

0 条评论