当前位置: 首页 > news >正文

有效 TCP RST

0. 少说两句

不论是攻击角度还是防御角度,tcp rst都可以发挥他阻断的作用,当然前提是可以有效的阻断TCP连接。在git上有些优秀的开源项目如:tcpkill,tcpwall都实现了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/

相关文章:

  • 46.全排列 | 51.N皇后
  • 正则表达式的说明》
  • 【Vue】基础系列(三三)指令语法-事件及其修饰符,动态样式,v-model的用法,数据持久化存在本地localStorage,自定义指令
  • 3D感知技术(3)相机成像模型及相机标定
  • ThinkPHP 接口开发过程
  • Pytorch常用的4种随机数生成方法
  • java毕业设计闲一品交易平台mybatis+源码+调试部署+系统+数据库+lw
  • java计算机毕业设计汽车销售系统源码+数据库+系统+lw文档+mybatis+运行部署
  • GNS3 vm 添加 H3C VSR1000 镜像、导入初始配置
  • docker镜像学习
  • 5.ARP地址解析协议
  • 多线程8锁案例演示
  • 尚好房 11_Session共享
  • 算法技巧-栈
  • 尚好房 12_redis缓存与AOP
  • [译]CSS 居中(Center)方法大合集
  • 【Amaple教程】5. 插件
  • Android 控件背景颜色处理
  • Druid 在有赞的实践
  • Gradle 5.0 正式版发布
  • LeetCode18.四数之和 JavaScript
  • Linux各目录及每个目录的详细介绍
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • MQ框架的比较
  • Mysql5.6主从复制
  • PHP CLI应用的调试原理
  • React+TypeScript入门
  • Redux系列x:源码分析
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • vue-cli3搭建项目
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 动态魔术使用DBMS_SQL
  • 你不可错过的前端面试题(一)
  • 如何学习JavaEE,项目又该如何做?
  • 延迟脚本的方式
  • 异常机制详解
  • ​2020 年大前端技术趋势解读
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • $.ajax中的eval及dataType
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (poj1.3.2)1791(构造法模拟)
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (三)终结任务
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (原)本想说脏话,奈何已放下
  • (转)视频码率,帧率和分辨率的联系与区别
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .Net Winform开发笔记(一)
  • ::before和::after 常见的用法
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现