TCP中的RST复位信号

TCP中的RST复位信号

在TCP协议中RST表示复位,用来关闭异常的连接,在TCP的设计中它是不可或缺的。

发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

TCP报文中有一个RST标志位,如下图:

产生RST的原因

1、端口未打开

服务器程序端口未打开而客户端来连接,例如telnet一个未打开的TCP的端口可能会出现这种错误。

比如主机A向主机B发送一个SYN请求,表示想要连接主机B的40000端口,但是主机B上根本没有打开40000这个端口,于是B就向主机A发送了一个RST。这种情况很常见。特别是服务器程序core dump之后重启之前连续出现RST的情况会经常发生。

2、提前关闭

比如主机A和主机B正常建立连接后,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。

3、在一个已关闭的连接上收到数据

4、请求超时


RST攻击

服务器A和服务器B之间建立了TCP连接,此时服务器C伪造了一个TCP包发给B,使B异常的断开了与A之间的TCP连接,这就是RST攻击。
那么伪造什么样的TCP包可以达成目的呢?我们至顶向下的看:

  • 假定C伪装成A发过去的包,这个包如果是RST包的话,毫无疑问,B将会丢弃与A的缓冲区上所有数据,强制关掉连接;
  • 如果发过去的包是SYN包,B会表示A已经发疯了(与OS的实现有关),正常连接时又来建新连接,B主动向A发个RST包,并在自己这端强制关掉连接;

这两种方式都能够达到复位攻击的效果。似乎挺恐怖,然而关键是C如何能伪造成A发给B的包呢?这里有两个关键因素,源端口和序列号。
一个TCP连接都是四元组,由源IP+源端口、目标IP+目标端口唯一确定一个连接。所以,如果C要伪造A发给B的包,要在上面提到的IP头和TCP头,把源IP、源端口、目标IP、目标端口都填对。这里B作为服务器,IP和端口是公开的,A是我们要下手的目标,IP当然知道,但A的源端口就不清楚了,因为这可能是A随机生成的。当然,如果能够对常见的OS如windows和linux找出生成source port规律的话,还是可以搞定的。
此外,伪造的TCP包里需要填序列号(SeqNum),如果序列号的值不在A之前向B发送时B的滑动窗口内,B是会主动丢弃的。所以我们要找到能落到当时的AB间滑动窗口的序列号。这个可以暴力解决,因为一个sequence长度是32位,取值范围0-4294967296,如果滑动窗口大小为65535的话,则最多只需要发65537(4294967296/65535=65537)个包就能有一个序列号落到滑动窗口内。RST包是很小的,IP头+TCP头也才40字节,算算我们的带宽就知道这实在只需要几秒钟就能搞定。

参考文档:

http://my.oschina.net/costaxu/blog/127394

http://www.cnblogs.com/lulu/p/4149562.html

时间: 2024-07-30 18:47:29

TCP中的RST复位信号的相关文章

TCP中的RST标志(Reset)详解

在谈RST攻击前,必须先了解TCP:如何通过三次握手建立TCP连接.四次握手怎样把全双工的连接关闭掉.滑动窗口是怎么传输数据的.TCP的flag标志位里RST在哪些情况下出现.下面我会画一些尽量简化的图来表达清楚上述几点,之后再了解下RST攻击是怎么回事. 1.TCP是什么? TCP是在IP网络层之上的传输层协议,用于提供port到port面向连接的可靠的字节流传输.我来用土语解释下上面的几个关键字: port到port:IP层只管数据包从一个IP到另一个IP的传输,IP层之上的TCP层加上端口

几种TCP连接中出现RST的情况(转载)

TCP RST 网络 linux 目录[-] 1 端口未打开 2 请求超时 3 提前关闭 4 在一个已关闭的socket上收到数据 总结 参考文献: 应该没有人会质疑,现在是一个网络时代了.应该不少程序员在编程中需要考虑多机.局域网.广域网的各种问题.所以网络知识也是避免不了学习的.而且笔者一直觉得TCP/IP网络知识在一个程序员知识体系中必需占有一席之地的. 在TCP协议中RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的.发送RST包关闭连接时,不必等缓冲区的包都发出去,直接

tcp nonblock connection rst

客户端(>5w)异步connect连接到server端,server端listen backlog设置为1024,发现存在部分客户端建立连接后,收到服务端的rst包. 先看下tcp监听套接字维护的两个队列(来自Unix网络编程) 测试模拟抓包如下: 解释:异步connect过快,导致server端listen已完成连接队列满了,后面接着来的connect请求放到未完成连接对列(SYN--->SYN,ACK, 等待客户端的ACK)中,当客户端的握手包ACK到来时,由于已完成连接队列已满,无法继续

【网络协议】TCP中的四大定时器

前言 对于每个TCP连接,TCP一般要管理4个不同的定时器:重传定时器.坚持定时器.保活定时器.2MSL定时器. 重传定时器 非常明显重传定时器是用来计算TCP报文段的超时重传时间的(至于超时重传时间的确定,这里涉及到一大堆的算法,书上有说,我这里不细谈了).每发送一个报文段就会启动重传定时器,假设在定时器时间到后还没收到对该报文段的确认,就重传该报文段,并将重传定时器复位,又一次计算:假设在规定时间内收到了对该报文段的确认,则撤销该报文段的重传定时器. 坚持定时器 上篇文章中已经提到了,主要是

TCP中close和shutdown之间的区别

该图片截取自<<IP高效编程-改善网络编程的44个技巧>>,第17个技巧. 如果想验证可以写个简单的网络程序,分别用close和shutdown来断开连接,然后用tcpdump查看交互过程,就一目了然了.本来我想自己写个程序验证,但是自己笔记本上没有linux环境,公司环境又不能通外网,所以就放弃了. TCP中close和shutdown之间的区别,布布扣,bubuko.com

/proc/net/tcp中各项参数说明

/proc/net/tcp中的内容由tcp4_seq_show()函数打印,该函数中有三种打印形式,我们这里这只列出状态是TCP_SEQ_STATE_LISTENING或TCP_SEQ_STATE_ESTABLISHED的情况,如下所示: netstat 的结果是读取/proc/net/tcp文件而来的 如何查看一个连接的创建时间 1.nestat -apn | grep xxx查看到对应的连接的进程pid和端口 2. 将上下游端口,转换为16进制xxxa xxxb 3.然后cat /proc/

TCP中在发送的数据的ACK未回来前,能继续发送其他数据包吗?

##基础## - 对应层数据的名称 - Application  <->  Package - Translation  <->  Segment - Networking   <->  Packet - DataLink     <->  Frame - TCP是一种基于字节流的协议,TCP 中的ACK是接收端期待发送端下一个发来的数据包的序列号 - MSS 是在建立连接时通过SYN数据包中的MSS选项里进行协商的(以太网的MTU能到1500,所以MSS可

TCP中的计时器

TCP中的计时器? (1)重传计时器 TCP发送完一个报文段,就设置一个专属于此报文段的计时器,规定时间内收到此报文段的确认,撤销计时器,时间走完还没收到确认包,重传此报文段并重置计时器. (2)持续计时器 客户端收到的确认包窗口是0,便停止发送数据了.过了一会,接收端缓过来劲了,继续发送一个更高序号的字节的确认包,它的窗口大于0,客户端如果收到此确认包,检测到窗口大于0,就会重新发送数据.但是如果此"激活"确认包万一丢失,双方都会永久静默下去(TCP不会重传ACK确认包).所以为每个

几种TCP连接中出现RST的情况

http://my.oschina.net/costaxu/blog/127394 在TCP协议中RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的.发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包.而接收端收到RST包后,也不必发送ACK包来确认. 其实在网络编程过程中,各种RST错误其实是比较难排查和找到原因的.下面我列出几种会出现RST的情况. 1 端口未打开 服务器程序端口未打开而客户端来连接.这种情况是最为常见和好理解的一种了.去tel