有效 TCP RST

0. 少说两句

不论是攻击角度还是防御角度,tcp rst都可以发挥他阻断的作用,当然前提是可以有效的阻断TCP连接。在git上有些优秀的开源项目如:tcpkilltcpwall都实现了tcp rst阻断,能看到这篇文章的小伙伴,我相信大部分是读过这些源码的,这些工具写的很好,其中tcpwall(国内小伙伴,GO语言开发)更胜一筹。虽然他们很好,但是还不够好,任然存在一些小问题,比如有些连接是rst不掉的。这些我会给出一些我的解决方案。

当然,这些工具的 前提是可以抓到TCP流 ,不管使用什么方法,镜像也好串行也罢,这也是我们整体文章大前提。

1. tcp rst流程

tcp rst流程其实很简单,简单到你第一眼看到这几个字,就会感觉这个我会。但是自己写tcp rst工具就会发现,你需要对TCP的 滑动窗口 机制有足够的了解,不然在构造rst包时会很迷茫。
流程如下:
流程图
具体可以参考tcpkill代码。
这个流程的关键是 构造RST包,构造RST包的目标是:构造出的RST包可以有效被接受。熟悉TCP协议应知道,只要发送的包序列号在对方接受窗口范围内,都可以被接收。
伪造一个TCP RST包需要:源IP、 目的IP、 源端口、 目的端口、 正确的序列号
五个关键信息,前四个信息通过抓包可以直接获取,源、目的信息调换位置即可,序列号则需要通过简单计算,得到合理的序列号才能使RST包生效。

2. 关键点: 序列号

几个问题:在回复TCP包的时候,seq和ack该如何填写?直接拿收到包的ack作为seq吗?是否需要运算?如何运算?seq和ack又代表着什么?
如果已经了然于胸,请跳过以下内容。

TCP协议主要可以分为两部分:一部分是连接管理,一部分是流量控制。这两部分内容使TCP协议成为实现复杂,但使用简单的协议。

序列号作为TCP数据包的一部分,会连接管理中被使用,但主要用于流量控制的滑动窗口。关于滑动窗口,这个动态展示非常的生动:滑动窗口演示滑动窗口就是缓存大小的管理方式,它通过控制窗口的大小可以达到控制流量的目的,具体内容这里不展开介绍,演示如下:流量控制演示

窗口大小和序列号的关系:
所有数据流的序列号需要在窗口的范围内,没有其他的线性关系(通过滑动窗口不能确定序列号的大小),初始序列号的产生是随机的,这样做可以加固TCP传输的安全性。原因可见:链接
可以通过wireshark查看窗口和序列号的关系,位于菜单栏 统计>>流量图 如下图:

在这里插入图片描述
wireshark展示的是TCP流的相对序列号,而非绝对序列号,相对序列号/确认号是和TCP会话的初始序列号相关联的,初始序列号在三次握手过程中初始化。通过wireshark的分析流量图可以看到,序列号的增加规律为:每次增加接收包的长度

我们对发送缓存区的每个字符都标上连续编号,序列号/确认号代表的意思:
数据方向 :A->B
seq (A)(发送):我如果发送数据,起始编号是多少
ack (A)(接收):我已经接收到了 B 哪些编号的数据(值为new_ack = B 的seq + B发送数据的长度)

对于A来说 如果再接收到B的数据,seq小于new_ack的将会被丢弃。
因此,回到tcp rst ,再构造包时发送的rst包的seq应该在接收方的接收范围内。

tcpkill做法为:使用ack值加上窗口值的n倍来增长seq。

	...
	seq = ntohl(tcp->th_ack);
	win = ntohs(tcp->th_win);
	
	for (i = 0; i < 10; i++) {
		seq += (i * win);
		...
		libnet_write(l);
	}
	...

这样做当然是有效的,但是tcpkill有时会失效。

3. 优化项

失效原因:
1、在使用libpcap抓包时,在ebpf中有缓存,导致发rst包不及时
2、序列号的计算为 窗口*n + ack,但是有些连接中窗口极小,但是window size scaling factor比较大,发送的seq增长过缓,导致其不在接收窗口范围内,rst失败

window size scaling factor是在握手过程中协商的,在发送数据过程中其并不可见

解决办法:
1、对于第一个问题,在使用libpcap时,使用其无缓存模式。
2、对于第二个问题,当窗口小于某值(如512)时,其最小为512。

4. 参考

TCP-RST 攻击与防御,看这一篇就够了
理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)
30张图解: TCP 重传、滑动窗口、流量控制、拥塞控制
https://www2.tkn.tu-berlin.de/teaching/rn/animations/gbn_sr/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值