动图图解!收到RST,就一定会断开TCP连接吗?

b59589330444d2d6de55b40ede9f9baa.png

若有收获,请记得分享和转发哦

想必大家已经知道小白的惯性,搞个标题,就是不喜欢立马回答。

就是要搞一大堆原理性的东西,再回答标题的问题。

说这个是因为小白这次会把问题的答案就放到开头吗?

不!

就不!

但是大家可以直接根据目录看自己感兴趣的部分。

之所以要先铺垫一些原理,还是希望大家能先看些基础的,再慢慢循序渐进,这样有利于建立知识体系。多一点上下文,少一点gap

好了,进入正题。

什么是RST

我们都知道TCP正常情况下断开连接是用四次挥手,那是正常时候的优雅做法。

异常情况下,收发双方都不一定正常,连挥手这件事本身都可能做不到,所以就需要一个机制去强行关闭连接。

RST 就是用于这种情况,一般用来异常地关闭一个连接。它是一个TCP包头中的标志位

正常情况下,不管是发出,还是收到置了这个标志位的数据包,相应的内存、端口等连接资源都会被释放。从效果上来看就是TCP连接被关闭了。

而接收到 RST的一方,一般会看到一个 connection reset 或  connection refused 的报错。

4ef0dac09bd10498c4aa0e1fe4710fb3.png
TCP报头RST位

怎么知道收到RST了?

6f3f3cc8d004eae32b991a7494fe1854.png

2e317a882c02c6c85d07ee7f7e50e5c2.gif

ResetByPeer

如果本端应用层尝试去执行写数据操作,比如send,那么应用层就会收到 Broken pipe 的报错,意思是发送通道已经坏了。

9c16c9cb74aad983a9e81687a2769762.gif

BrokenPipe

这两个是开发过程中很经常遇到的报错,感觉大家可以把这篇文章放进收藏夹吃灰了,等遇到这个问题了,再打开来擦擦灰,说不定对你会有帮助。

335c42a25571d4e801ffd11a36a99735.png

d3e8c08b4bba7ef980bc13ee21e44641.png

服务端listen 方法会创建一个sock放入到全局的哈希表中。

此时客户端发起一个connect请求到服务端。服务端在收到数据包之后,第一时间会根据IP和端口从哈希表里去获取sock

81d607aefee95333cc5aef95788aa707.png

fa19818ab9fa0524bfd89a9563446619.png

12aa3232af0f23268827dcecfb3a9f74.png

2f09c6f57d18f145872747b5fe2e9cc3.png

10908bb52a60c9617a537007456d9a5e.png

6507f1414a2a3b9d9d125466c0531747.png

7cdcc6595d1ebf3036ced2d165d1f139.png

a0f91f7a8aaa17182f7d13134f43c5ef.png

79e7ed9efee1ac986413b98dcdfeed38.png

baa9cb2c7724edc1b9b6be7e103e5c83.png

fd79269b8805052e8e9d2a9bb610e0a8.gif

recvbuf非空
远端提前关闭

远端已经close()socket,此时本端还尝试发数据给远端。那么远端就会回一个RST。

82233b81b43aae8368dfb0caf2fb8a95.png

a9014f4d9467a1fadea96a8eb41d04b7.png

4682cc8df16b65c333550e3b7671a4fe.png

RST丢失

RST丢了,问题不大。比方说上图服务端,发了RST之后,服务端就认为连接不可用了。

如果客户端之前发送了数据,一直没等到这个数据的确认ACK,就会重发,重发的时候,自然就会触发一个新的RST包。

而如果客户端之前没有发数据,但服务端的RST丢了,TCP有个keepalive机制,会定期发送探活包,这种数据包到了服务端,也会重新触发一个RST。

ad47bb52794e12ef78f5559d40e0da03.png

a44f381c024e2b74ad95ab57a8903d0f.png

e05f85b71f828f2ff51916b895e56ead.png

20da7e0491e4ead1e763ce3181ee79d0.png

a92fcc879967163f7b88e736aa616dc9.png

4666e3fa7c1c747f4d99d071a5c6da25.png

5809aa01c9755c21367052a49dc77aea.png

上图是抓包的结果,用scapy随便伪造一个seq=5的包发到服务端(端口9090),服务端回复一个带有正确seq值的challenge ack包给客户端(端口8888)。

利用challenge ack获取seq

上面提到的这个challenge ack ,仿佛为盲猜seq的老哥们打开了一个新世界。

在获得这个challenge ack后,攻击程序就可以以ack值为基础,在一定范围内设置seq,这样造成RST攻击的几率就大大增加了。

9fd11e079bf59506028cf75996b38003.png

利用ChallengeACK的RST攻击

总结

  • RST其实是TCP包头里的一个标志位,目的是为了在异常情况下关闭连接。

  • 内核收到RST后,应用层只能通过调用读/写操作来感知,此时会对应获得 Connection reset by peer 和Broken pipe 报错。

  • 发出RST后不需要得到对方的ACK确认包,因此RST丢失后对方不能立刻感知,但是通过下一次重传数据或keepalive心跳包可以导致RST重传。

  • 收到RST包,不一定会断开连接,seq不在合法窗口范围内的数据包会被默默丢弃。通过构造合法窗口范围内seq,可以造成RST攻击,这一点大家了解就好,千万别学!

07fbc7437a8409c2296575e4e25c2105.png

轻松一刻,欣赏美景

081db2dae2676b3fc9df63c5b5671940.png

点击下方

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值