暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

IT技术精选文摘 2021-11-06
1078

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

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

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

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

不!

就不!

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

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

好了,进入正题。

什么是RST

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

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

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

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

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

TCP报头RST位


怎么知道收到RST了?

ResetByPeer

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

BrokenPipe

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

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

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

recvbuf非空


远端提前关闭

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

RST丢失

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

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

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

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


利用challenge ack获取seq

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

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

利用ChallengeACK的RST攻击


总结

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

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

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

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


轻松一刻,欣赏美景

点击下方

文章转载自IT技术精选文摘,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论